Android异常与性能优化相关面试问题-内存泄漏面试问题讲解

Java内存泄漏基础知识:

  • Java的内存的分配策略

    a、静态存储区:也叫方法区,主要是存放一些静态数据及全局变量等,在程序编译时就已经分配好了,并且在静态存储区中存放的变量在整个程序运行期间都存在。
    b、栈区:执行方法时,方法中的局部变量会在栈上创建内在空间,并在方法执行结束之后这些变量及所持有的内存会自动释放。因为栈内存分配运算内置于处理器当中,所以效率很高,但是栈区的容量有限。
    c、堆区:也就动态内存分配,通常是我们new出来的内存,在不使用时会由java回收器来负责回收。

  • Java是如何管理内存的
    是由虚拟器GC来释放的,为了能够正确的释放对象,必须监控每个对象的运行状态,包括对像的申请、引用、被引用、复制等等,下面来看一张图更好的理解GC的工作原理:

    其中main是根顶点,根顶点可达的对象都是有效的对象,如图o1、o2,GC的时候是不会回收这些对象的,而Obj2是根顶点不可达到的对象,所以说这个对象是可以被回收的。

  • Java中的内存泄漏
    内存泄漏是指无用对象(不再使用的对象)持续占有内存或无用对象的内存得不到及时释放,从而造成的内存空间的浪费。

Android内存泄漏:

  • 单例:

    修复方法:

  • 匿名内部类:

    修复如下:
  • handler:

    而之所有上面的写法会存在泄漏,是由于是消息队列在一个Looper线程中不断的轮循处理消息,当MainActivity退出的时候消失队列中还有未处理的消息或正在处理的消息,而消息队列中的Message持有了mHandler的实例引用,而mHandler又持有MainActivity的引用,所以就容易造成泄漏了。
    修复如下:

  • 避免使用static变量:
    由于static变量在app退出时也不会被释放,根据app内存管理机制,占内存较大的进程将优先被回收,如果app被回收那存在的变量是不安全的,避免的方法就是可以使用懒加载避免使用static,如果非要使用那一定要对这类静态变量的生命周期进行管理。
  • 资源未关闭造成的内存泄漏:
    如广播、cursor、Bitmap、contentProvider等。
  • AsyncTask造成的内存泄漏:
    在onDestroy()中主动调用一下cancel方法。
  • Bitmap不用时需要调用recycle()方法将C区的内存进行释放。
原文地址:https://www.cnblogs.com/webor2006/p/8987905.html