谈起内存抖动,我们先复习一下JVM内存空间的情况,如下图
内存抖动的原因
内存频繁的分配与回收,(分配速度大于回收速度时)最终会产生OOM。
频繁分配内存两个例子:
循环里面是有+号进行字符串拼接,可以改用StringBuffer/StringBuilder进行拼接。
WebView显示图片,WebView里面的内存问题是无解的,可以开启另一个进程展示WebView所在activity或改进算法减少耗时。
回收算法
1、标记清除算法Mark-Sweep,内存碎片多,速度快。
2、复制算法Copying,减少内存碎片,牺牲了内存空间,速度较慢。
3、标记压缩算法Mark-Compact,减少内存碎片,折中方式。
4、分代收集算法,Android使用的算法。
注意:Permanent和垃圾回收没什么关系,主要用来存放类,方法信息,也能作为常量池使用,不同VM不同实现,有些没这个区。
以下收集器不是单独使用,而是混合使用,新生代与老年代采用的收集器是不一样的。
a、Serial串行收集器
b、ParNew 收集器
c、Parallel Scavenge收集器
吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间)。
d、Serial Old收集器
e、Parallel Old收集器
f、CMS 收集器,老年代Android使用的是这种机制。
CMS采用"标记-清理"算法实现以获取最短回收停顿时间为目标的收集器,增加了CPU的负担
初始标记:标记一下GC Roots能直接关联到的对象
并发标记:进行GC Roots Tracing 的过程
重新标记:是为了修正并发标记期间因用户程序继续运行而导致标记产品变动的那一部分对象的标记记录
并发清除:清除不能到达GC Roots的对象
重置线程:更新之前使用过的数据