一、内存抖动
短时间大量的对象创建及销毁,伴随着频繁的gc(比如字符串拼接,在class编译的后,能看到大量的StringBuilder被创建出来)。
内存抖动会造成卡顿、oom现象。为什么?
卡顿的原理:
android回收机制默认使用的是cms机制,如果内存满了,gc开始工作,工作的时候,会把所有的线程都挂起包括主线程,同时采集你创建的无用对象,并收集,销毁。此时就会有卡顿现象。如果频繁的创建对象,就会频繁的gc,同时采集对象的时间也会加大,卡顿现象就会加大。
oom现象:
讲解之前首先说一下jvm垃圾回收算法有三种:复制、标记清楚、标记整理(此处不详细讲解)。还有新生代、老年代详情看下面的一个文章
https://blog.csdn.net/yrwan95/article/details/82826606
上面文章补充一下对象提前进入老年代有下面几个方式
1、大对象
2、存活时间达到一定的阀值(默认是6,可以修改)
3、内存对象存活的同一年龄段总数大于超过年轻代的一半。则会将等于或者大于这一段的年龄带对象提前进入老年代
看完之后,比如现在有一个100字节的数组要放入老年代中。但是由于频繁的gc。造成了大量的内存碎片,这时候虽然空闲空间有1000字节空间,但是连续100字节空间达不到,这时数据放不下去就会导致oom。
预防抖动
使用对象池,例如模拟handle中的Message的obtain创建对象。
2、内存泄露
采用的可达性分析法,通过一系列的“GC Roots”对象作为起点,从这些节点开始往下搜索,搜索所有的引用。找不到则证明对象不可用。
预防泄露
可以使用软引用、弱引用