android 内存优化是作为一个android开发人员必须要掌握的知识之一,它能够让我们的app更加的流程增加用户的体验感。
java内存分配策略:
1.静态存储区(方法区):主要存放静态数据、全局static数据和常亮。这块内存在程序编译时就已经分配好,并且在整个程序运行间都存在。
2.栈区:方法执行时被执行,方法体内的局部变量都在栈上创建,并在方法执行结束时这些局部变量所持有的内存将被自动释放。因为栈内存分配运算内置于处理器指令集中,效率很高,但是分配的内存是有限的。
3.堆区:又称为动态分配区,通常是值在程序运行时直接new出来的对象。这部分内存在不使用的时候将由java垃圾回收期来负责回收(new 出来的对象以及该对象中的所有成员变量都在堆内存中)。
tips:堆与栈的区别
栈中的变量生命周期随着方法的结束而结束,系统自动回收
堆内存由GC负责回收
举个例子:
public class Demo { private final String TAG = Demo.class.getSimpleName();//常量, 方法区 private static int m = 0;//静态变量, 方法区 private int n = 1;//成员变量, 堆区 private void learn(){ int k = 2;//局部变量, 栈区 Demo demo = new Demo();// demo局部变量, 栈区; Demo实例,堆区 } }
java垃圾回收机制:
java中内存的分配是由程序来完成的,而内存的释放是由垃圾收集器(GC)完成的,程序猿不需要通过函数调用来释放内存,但是随之而来就可能造成内存泄漏(即:new出来的对象无法被回收)。
可达性分析算法:(1).以 "GC ROOT"对象作为起点向下搜索;(2)每走过一个对象,就生成一条引用链。(3)从根开始到搜索完成,生成一颗引用树,那些GC ROOT达不到的对象就是可以回收的。
在java中GC ROOT包括:虚拟机栈中引用的对象;方法区中静态属性实体引用的对象;方法区中常量引用的对象;本地方法栈中JNI引用的对象。
常见的垃圾回收算法:
1.引用计数:对象增加一个引用,计数器加1,反之减1.计数为0则回收(循环引用问题)
2.标记-清除收集器:新开线层遍历对象图标记可达到的对象,然后扫描堆栈寻找未标记的对象释放他们所占的内存(造成大量内存碎片)
3.标记-清除-压缩收集器:增加一个压缩步骤,把标记的对象复制到新的区域中,避免内存碎片。
4.复制收集器:将堆分成两块区域1和2,初始的时候程序使用1区域,new的对象放到区域2,当gc运行时将可到达的对象复制到区域2,回收区域1.(内存缩小为原来的一半,复制生命周期长的对象效率低)
5.增量收集器:把堆分成n块区域,每次只回收一块区域,减小其他线程暂停时间。
6.分代收集器:把堆分成n块区域,但是每块区域存放对象的生命周期不同,生命周期短的放在一个区域,生命周期长的放在一个区域。并且不同的区域采用不同的回收算法以提高性能。
Android的垃圾回收机制:原始JVM中的GC机制在Android中得到了很大程度上的优化。Android里面是一个三级Generation的内存模型,最近分配的对象 会存放在Young Generation区域,当这个对象在这个区域停留的时间达到一定程度,它会被移动到Old Generation,最后到Permanent Generation区域每一个级别的内存区域都有固定的大小,此后不断有新的对象被分配到此区域,当这些对象总的大小快达到这一级别内存区域的阀值时,会触发GC的操作,以便腾出空间来存放其他新的对象。