内存抖动是指内存频繁的分配和回收, 而频繁的gc会导致卡顿, 严重时和内存泄漏一样会导致OOM
垃圾回收
在对对象进行回收前需要对垃圾进行采集, 不同的虚拟机实现可能使用不同的垃圾收集算法, 不同的手机算法的实现也不尽相同, 不同的算法各有各的优劣势
常用的收集算法有:
1. 标记-清除算法 Mark-Sweep
算法分为标记和清除两个阶段, 首先标记出所有需要回收的对象, 在标记完成后统一回收被标记的对象
标记-清除算法不会进行对象的移动, 直接回收不存活的对象, 因此会造成内存碎片
2. 复制算法Copying
复制算法, 它将可用内存按照容量划分为大小相等的两块, 每次只使用其中的一块. 当这一块的内存用完了, 就将还存活的对象复制到另外一块上, 然后再把已使用过的内存空间一次清理掉
这样使得每次都是对其中的一块进行内存回收, 内存分配时也就不用考虑内存碎片等复杂的情况, 只要移动堆顶指针, 按顺序分配欸村即可, 实现简单, 运行高效. 知识这种算法的代价是将内存缩小为原来的一半, 持续复制生存起的对象则导致效率降低
复制收集算法是在对象存活率较高时就要执行较多的复制操作, 效率将会变低. 更关键的是, 如果不想浪费50%的空间, 就需要有额外的空间进行分配担保, 以应对被使用的内存中所有对象都100%存活的极端情况
3. 标记-压缩算法 Mark-Compact
标记的过程与"标记-清除"算法一样, 但后续步骤不是直接对可回收对象进行清理, 而是所有存活的对象都向一端移动, 然后直接清理掉边界以外的内存.
标记-压缩算法虽然缓解的内存碎片问题, 但是它也引用了额外的开销, 比如说额外的空间来保存迁移地址, 需要遍历多次堆内存等
4. 分代收集算法
无论是一般的JVM还是DVM, 不会只使用一种垃圾收集算法. 它会根据内存的划分实现不同的收集算法