「金三银四涨薪季,我命由我不由天!」
image.png对象被判定为不可达对象之后就“死”了吗image.png垃圾收集算法「已经能够确定一个对象为垃圾之后,接下来要考虑的就是回收,怎么回收呢?得要有对应的算法,下面介绍常见的垃圾回收算法。高效健壮」
标记-清除(Mark-Sweep)「标记」「找出内存中需要回收的对象,并且把它们标记出来」
「此时堆中所有的对象都会被扫描一遍,从而才能确定需要回收的对象,比较耗时」
image.png「清除」「清除掉被标记需要回收的对象,释放出对应的内存空间」
image.png缺点
标记清除之后会产生大量不连续的内存碎片,空间碎片太多可能会导致以后在程序运行过程中需要分配较大对象时,无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作。(1)标记和清除两个过程都比较耗时,效率不高(2)会产生大量不连续的内存碎片,空间碎片太多可能会导致以后在程序运行过程中需要分配较大对象时,无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作。标记-复制(Mark-Copying)
「将内存划分为两块相等的区域,每次只使用其中一块,如下图所示:」
image.png当其中一块内存使用完了,就将还存活的对象复制到另外一块上面,然后把已经使用过的内存空间一次清除掉。
image.png缺点:空间利用率降低。
标记-整理(Mark-Compact)「复制收集算法在对象存活率较高时就要进行较多的复制操作,效率将会变低。更关键的是,如果不想浪费50%的空间,就需要有额外的空间进行分配担保,以应对被使用的内存中所有对象都有%存活的极端情况,所以老年代一般不能直接选用这种算法。」
「标记过程仍然与"标记-清除"算法一样,但是后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存。」
「其实上述过程相对"复制算法"来讲,少了一个"保留区"」
image.png分代收集算法「既然上面介绍了3中垃圾收集算法,那么在堆内存中到底用哪一个呢?」
「Young区:复制算法(对象在被分配之后,可能生命周期比较短,Young区复制效率比较高)」
「Old区:标记清除或标记整理(Old区对象存活时间比较长,复制来复制去没必要,不如做个标记再清理)」
垃圾收集器「如果说收集算法是内存回收的方法论,那么垃圾收集器就是内存回收的具体实现。」
image.pngSerial「Serial收集器是最基本、发展历史最悠久的收集器,曾经(在JDK1.3.1之前)是虚拟机新生代收集的唯一选择。」
「它是一种单线程收集器,不仅仅意味着它只会使用一个CPU或者一条收集线程去完成垃圾收集工作,更重要的是其在进行垃圾收集的时候需要暂停其他线程。」
优点:简单高效,拥有很高的单线程收集效率缺点:收集过程需要暂停所有线程算法:复制算法适用范围:新生代应用:Client模式下的默认新生代收集器image.pngSerialOld
**SerialOld收集器是Serial收集器的老年代版本,也是一个单线程收集器,不同的是采用"**「标记-整理算法」",运行过程和Serial收集器一样。
image.pngParNew「可以把这个收集器理解为Serial收集器的多线程版本。」
优点:在多CPU时,比Serial效率高。缺点:收集过程暂停所有应用程序线程,单CPU时比Serial效率差。算法:复制算法适用范围:新生代应用:运行在Server模式下的虚拟机中首选的新生代收集器image.pngParallelScavenge
「ParallelScavenge收集器是一个新生代收集器,它也是使用复制算法的收集器,又是并行的多线程收集器,看上去和ParNew一样,但是ParallelScanvenge更