标记-清除
把非垃圾对象进行标记,把未标记的进行清除。这是最基础的算法,别的算法都是基于此不断改进
不足的地方
- 效率不高(要看跟谁比,比如标记-复制就要快些)
- 内存碎片:会产生大量不连续的内存碎片,导致可能无法给大对象分配内存
标记-整理
还是要先标记哪些对象是垃圾,标记了先不着急清除,先把非垃圾对象移动到一端,然后把边界之外的(就是垃圾对象)清除
标记-复制
- 把内存分为两块,只使用其中一块,这样标记的时间肯定就少(毕竟只检索一半的内存)
- 把存活对象顺序复制到另一块内存(同时清理本部分),不会有内存碎片
- 缺点是浪费一半空间,典型的空间换时间
- 新生代的垃圾回收采用这种算法,但是并不是把整个新生代内存一分为二,这样就太浪费了,而是只是新生代中较小的幸存区分为两块
分代垃圾回收
这并不是一种新的算法,而是对不同代采用不同的垃圾回收算法
- 新生代:采用 标记-复制 算法
- 老年代:采用 标记-清除 或者 标记-整理 算法
新生代不适合标记-整理吗?
同理,老年代不适合标记-复制吗?
- 新生代发生的 GC 频率高,所以需要时间高效的算法;并且 Eden 和 两个幸存区的比例默认是 8:1:1,所以新生代使用率是可以达到 90%,空间上也不是特别浪费
- 老年代发生 GC 频率不高,并且内存占用比较大,所以 标记-复制 不合适