垃圾回收算法
1. 核心思想
Java是如何实现垃圾回收的呢?简单来说,垃圾回收要做的有两件事:
1、找到内存中存活的对象
2、释放不再存活对象的内存,使得程序能再次利用这部分空间
2. 垃圾回收算法历史
1960年John McCarthy发布了第一个GC算法:标记-清除算法。
1963年Marvin L. Minsky发布了复制算法。
本质上后续所有的垃圾回收算法,都是在上述两种算法的基础上优化而来:
3. 垃圾回收算法的评价标准
Java垃圾回收过程会通过单独的GC线程来完成,但是不管使用哪一种GC算法,都会有部分阶段需要停止所有的用户线程。这个过程被称之为Stop The World简称STW,如果STW时间过长则会影响用户的使用。
所以判断GC算法是否优秀,可以从三个方面来考虑:
3.1 吞吐量
吞吐量指的是CPU用于执行用户代码的时间与CPU总执行时间的比值,即吞吐量=执行用户代码时间/(执行用户代码时间+GC时间)。吞吐量数值越高,垃圾回收的效率就越高。
比如:虚拟机总共运行了100分钟,其中GC花掉1分钟,那么吞吐量就是99%
3.2 最大暂停时间
最大暂停时间指的是所有在垃圾回收过程中的STW时间最大值。比如如下的图中,黄色部分的STW就是最大暂停时间,显而易见上面的图比下面的图拥有更少的最大暂停时间。最大暂停时间越短,用户使用系统时受到的影响就越短。
3.3 堆使用效率
不同垃圾回收算法,对堆内存的使用方式是不同的。比如标记清除算法,可以使用完整的堆内存。而复制算法会将堆内存一分为二,每次只能使用一半内存。从堆使用效率上来说,标记清除算法要优于复制算法。 上述三种评价标准:堆使用效率、吞吐量,以及最大暂停时间不可兼得。
一般来说,堆内存越大,最大暂停时间就越长。想要减少最大暂停时间,就会降低吞吐量。不同的垃圾回收算法,适用于不同的场景。