- 对象存活性判断
1 引用计数法
2 对象可达性分析 (JVM虚拟机使用为主)
垃圾回收
最基本的做法是分代回收。内存中的区域被划分成不同的世代,对象根据其存活的时间被保存在对应世代的区域中。一般的实现是划分成3个世代:年轻、年老和永久。内存的分配是发生在年轻世代中的。当一个对象存活时间足够长的时候,它就会被复制到年老世代中。对于不同的世代可以使用不同的垃圾回收算法。进行世代划分的出发点是对应用中对象存活时间进行研究之后得出的统计规律。一般来说,一个应用中的大部分对象的存活时间都很短。比如局部变量的存活时间就只在方法的执行过程中。基于这一点,对于年轻世代的垃圾回收算法就可以很有针对性。
- System.gc()
通知GC开始工作,但是GC真正开始的时间不确定
算法
- 标记-清除算法 Mark-Sweep
标记清楚算法分两个阶段:“标记”和“清除”。首先,JVM将可以回收的对象进行标记,之后对所有对象进行扫描,将有标记的对象进行回收
- 缺点
算法效率不高,并且在清理完成后会产生内存碎片。清理完成后,如果有大对象需要连续的内存空间时,还需要进行碎片整理。
- 标记整理算法 Mark-Compact
与标记清理算法类似,都是标记回收。但是标记整理算法在清理之后会将依然存活的对象移动到一起,这就使得内存得以连续。
- 优点
标记整理算法可以提高内存使用效率,因为在内存整理之后,当程序需要为新对象分配空间时就无需在内存碎片中搜索大小合适的碎片。
- 复制算法将要进行垃圾回收的内存分成不同的模块。当在A内存模块中进行垃圾回收时,将存活的对象复制到B内存模块,然后清理A内存模块。
- 优点
算法实现简单,运行效率高。 - 缺点
由于每次只能使用其中一部分内存,导致内存利用率不高。
总结
新生代:复制算法
老年代:标记整理算法
永久代:标记整理算法
Oracle在Java Garbage Collection中详细介绍了不同的分区如何使用不同的垃圾回收算法,同时也介绍了对象如何从新生代不断迭代进入永久代的。
除此之外,垃圾回收器也是垃圾回收中重要的一部分。常见的垃圾收集器有:
- 串行GC (Serial GC)
- 并行回收GC (Parallel Scavenge)
- 并行GC (ParNew GC)
不同的垃圾回收器可以通过不同的命令来指定使用,例如:
-XX:+UseSerialGC
-XX:+UseParallelGC
网友评论