昨天,我一个朋友给我说他在抖音上发了一个短视频,获得了 300 个赞。我说,你要么被抖音废了,要么就废了(卸载)抖音,要么你就把抖音玩到极致,成为抖音网红。

我在下载抖音的时候,玩了一个小时就把它卸载了。因为我深知,要想成功,便不要沉迷于能轻易给你短期快感的一切东西。

其实,作为程序员也是一样的。平时工作,你面向百度编程。慢慢的你会迷上搜索,无法摆脱它。不想看书,也不想进步去学习,因为所有的东西,在你眼里看起来是一搜索就能解决。其实,这只是你废了的开始。

今天我给大家讲一下,进阶中级、高级、专家级。的必备课,GC 中的 MinorGC。

JVM 中的堆,一般分为三大部分:新生代、老年代、永久代。新生代通常使用 MinorGC,老年代通常使用 MajorGC,永久代通常使用 Full GC。

你面试过程中的拦路虎 MinorGC_java

新生代主要是用来存放新生的对象。一般占据堆的1/3空间。由于频繁创建对象,所以新生代会频繁触发 MinorGC 进行垃圾回收。新生代 MinorGC 又通常被分为:Eden 区、ServivorFrom、ServivorTo 三个区。

MinorGC 通常采用复制算法。流程是先复制,再清空,最后互换。

复制的过程很简单。首先,Eden 区满的时候回出发第一次 GC,把存活的对象拷贝到 SurvivorFrom 区,当 Eden 区再次触发 GC 的时候会扫描 Eden 区和 From 区,对这两个区域进行垃圾回收。

经过这次回收后还存活的对象,则直接复制到 To 区,同时将这些对象的年龄 +1。如果有对象年龄已经达到了老年的标准(年龄阈值,可以通过-XX:MaxTenuringThreshold来设置),则直接复制到老年代。

发生 MinorGC 后,Eden 和 ServivorFrom 区的对象,就被复制到其他区了。

另外一个需要注意的是,如果新创建的对象占用内存很大,则直接分配到老年代。并且 SurvivorTo 区是没有进行任何回收动作的。

清空就很好理解了。因为经过 MinorGC 后,Eden 和 ServivorFrom 区的对象,就被复制到老年代或者 SurvivorTo 区。这个时候就可以对 Eden 区和 ServivorFrom 进行清空了。

清空之后,还有一个互换动作。就是把 SurvivorTo 的对象互换给 ServivorFrom 区。SurvivorTo 和 SurvivorFrom 互换,原来的 SurvivorTo 称为下一次 GC 时的 SurvivorFrom 区。部分对象会在 From 和 To
区域中来回复制,如此交换15次(JVM参数 MaxTenuringThreshold决定,默认参数是15),最终如果还是存活,就存入老年代。

这就是 MinorGC,非常的简单。大家在面试中只需要记住,ServivorTo 一开始是空的,复制算法流程是先复制,再清空,最后互换,另外一个需要注意的是,如果新创建的对象占用内存很大,则直接分配到老年代。还有就是 Eden 和 Survivor 区的默认占比为 8:1。回答到这些关键点,至少我个人会算面试者过关。

更多面试题,如:GC触发的条件?什么时候触发?GC回收对什么东西进行回收?GC回收做了什么或者说是操作了什么,怎么操作的?等等这些面试题,可以通过我的面试题小程序学习到!