内存不够用?讲讲Android开发超常见的内存泄露以及解决

移动开发
有没有感觉自己的Android手机开机之后,可用内存不断减少,很大一部分原因就是因为内存泄露了,这部分泄露的内存无法被回收,所以可用内存越来越少。发生了内存泄漏的问题,该怎么解决呢?

[[140732]]

有没有感觉自己的Android手机开机之后,可用内存不断减少,很大一部分原因就是因为内存泄露了,这部分泄露的内存无法被回收,所以可用内存越来越少;

什么是内存泄露?GC无法回收原本应该被回收的对象,这个对象就引发了内存泄露

1.Bitmap使用完忘记回收,因为bitmap实现部分是通过JNI调用了Native方法,GC机制无法正常回收 Bitmap申请的这部分内存空间(API10之前是这样的,之后分配在Heap中,不过为了兼容老版本...显示的调用一下recycled,也能让GC更快的回收调自己);

那Bitmap应该怎样回收呢?

// bitmap!=null要放在前面,如果bitmap为空再去调用isRecycled方法便会报错 
 
if(bitmap!=null&&!bitmap.isRecycled){ 
 
      bitmap.recycled(); //回收bitmap 
 
      bitmap = null;      //使bitmap对象变为虚引用的状态,让GC更快的回收 
 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

接下来,讲两个更为常见的内存泄露,大家根据这两个可以自行扩展

btn_hint.setOnClickListener(new View.OnClickListener() { 
 
@Override 
 
    public void onClick(View v) { 
 
        Toast.makeText(MainActivity.this"Hello", Toast.LENGTH_SHORT).show(); 
 
   } 
 
}); 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

是不是很常见,平时可能也是这样写的(将其封装意义一样,只要引用了当前activity),你可能想问,这里有什么问题吗?

问题在于如果用户在Toast消失之前,用户按了返回键,这个Activity就引起了内存泄露,

原因? Toast持有了当前Activity,导致Activity无法被GC销毁

解决方法:让Toast持有ApplicationContext;其实只要不是Layout,Context都可以使用ApplicationContext;

顺便讲个小技巧:在非Activity中,正常是不能直接getContext来拿到Context的,获取资源有需要靠Context,这时可以考虑在自己的Application中维护一个全局的Context,供无法直接拿到Context的类使用,省的参数传来传去(视图相关的不建议使用ApplicationContext)

 

private static Context mContext; 
 
public static MyApplication getInstance() { //供外界调用... 
 
     return mApplication; 
 

 
@Override 
 
public void onCreate() { 
 
    super.onCreate();  
 
    mContext = getApplicationContext();    
 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.

另一个常见的...内存泄露

new Thread() { 
 
    public void run() { 
 
    //网络请求 
 
    }; 
 
}.start(); 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

这里也有问题?你tm逗我?

在Activity中 新建一个线程,进行网络请求,如果线程未结束,用户按了返回键,同样内存泄露

原因:该Thread是匿名内部类,所以会隐式的持有外部类(这里也就是Activity)

解决方式:多种多样; 不使用匿名内部类,或者整个应用维护一个线程池,或者维护一个线程队列,后两种都是让线程不依赖于Activity从而达到避免内存泄露的目的;

资源获取等等很多地方都需要用到Context,很多地方都会用到匿名内部类,这也就导致了这里存在很大的内存泄露隐患,但平时很多小伙伴可能还没有注意到,希望这篇文章能给你一些启发。

责任编辑:倪明
相关推荐

2021-03-15 23:11:12

内存虚拟化技术

2013-06-14 13:27:36

内存Linux交换分区

2023-05-17 07:28:18

电脑16GB内存

2019-07-24 14:05:17

Redis内存集群

2024-08-05 11:08:53

内存File项目

2019-07-25 15:23:05

Redis电脑数据库

2019-11-15 10:41:10

Vim分屏终端

2011-06-16 10:27:55

.NET内存泄漏

2013-12-19 10:08:52

AWS服务器

2013-05-02 09:16:16

程序员

2023-06-12 07:20:39

2013-10-23 14:28:30

2017-03-23 11:24:26

Windows 10Windows系统盘

2018-11-22 14:34:01

局域网IP扩容

2016-11-25 15:03:33

FacebookWIFI

2024-07-25 12:33:45

2010-08-10 10:10:34

Flex内存泄露

2021-08-08 08:17:45

事件响应日志网络安全

2019-04-04 13:11:37

React内存泄露memory leak
点赞
收藏

51CTO技术栈公众号