学习目标:
Android中的内存分布和泄漏
学习内容:
1.内存模型与分布
- 方法区
加载的类信息,常量,静态变量,及时编译器编译后的代码等数据。内存优化时这一部分主要考虑是不是加载了很多不必要的第三方库。这部分的内存减少主要是常量池的回收和类的卸载(类卸载条件:无引用,类加载器可卸载) - 堆
所有的对象都在这个区域产生,该区域属于线程共享的区域,所以写代码时更要注意多线程安全。这个内存区域的大小变化主要是对象的创建和回收,比如:如果短时间内有大量的对象创建和回收,可能会造成内存抖动,如果对象创建之后一直回收不掉,则会导致内存泄漏,严重的内存泄漏会导致频繁的gc,从而是界面卡顿。 - 虚拟机栈
这个区域描述的是java方法执行的内存模型,我们常说的方法栈的入栈就是将方法的栈帧存储到虚拟机栈,这个区域是线程私有的,其生命周期就是线程的生命周期。也就是说每个线程都会有,默认一个线程的线程栈大小是1M,这不包括在方法中产生的其他对象的大小。这一块我们能控制的就是线程的数量,特别是程序中没有使用线程池或者使用的多个第三方库都带有线程池的情况。 - 本地方法栈
同虚拟机栈的作用非常类似,是为虚拟机执行native方法服务的,所以需要注意的地方也和虚拟机栈一样,特别是使用了第三方so的情况 - 程序计数器
当前线程执行的虚拟机字节码的行号记录器,占用的内存较小,可以不考虑
关于上面提到的内存泄漏,内存抖动请参考内存抖动是什么?怎么解决?内存抖动是什么?怎么解决?垃圾回收机制是什么样的?
再来介绍一下我们的每个java对象内存的结构
分代年龄是在GC的时候用到的标志位。
以上,我们还需要工具来分析内存泄漏,内存泄漏的几种情况在上面有链接,我用的分析工具是 MemoryAnalyzer或者leakcanary,具体使用就不多介绍了。