Minor GC、Major GC与Full GC

先简单介绍一下:
Minor GC:从年轻代空间(包括 Eden 和 Survivor 区域)回收内存被称为 Minor GC。
Major GC:是清理老年代。
Full GC:是清理整个堆空间—包括年轻代和老年代。
Minor GC、Major GC与Full GC
年轻代是大多数新对象创建和销毁的地方,对象从Young generation区域消失的过程我们称之为”minor GC“ 当年轻代满时,会引发“minor GC”。
新生代分为三个空间:
Eden、Survivor from、Survivor to
为什么要把新生代分为三个区呢,接下来就解释原因:
1.将任何新对象分配给eden空间。 两个survivor空间开始为空。
Minor GC、Major GC与Full GC
2.当Eden满的时候,Minor GC 被触发
Minor GC、Major GC与Full GC
3.被引用的对象被移动到第一个survivor空间。 当eden空间被清除时,未被引用的对象被删除
Minor GC、Major GC与Full GC
4.在下一个次要的GC中,同样的事情发生在eden空间。 未引用的对象被删除,引用的对象被移动到survivor空间。 然而,在这种情况下,它们被移动到第二幸存者空间(S1)。 另外,来自第一survivor空间(S0)的最后一个Minor GC的对象的年龄增加并被移动到S1。 一旦所有幸存的物体都移动到S1,S0和eden都被清除。 请注意,我们现在在幸存者空间中有不同的老化对象。
Minor GC、Major GC与Full GC
5.在下一个次minor GC中,重复相同的过程。 但这次survivor空间转换。 被引用的对象被移动到S0。 幸存的对象逐渐老化。 Eden和S1被清除。
Minor GC、Major GC与Full GC
6.当这种minor GC过程不断进行,当年龄达到一定年龄的门槛(这里假设是8 )时,他们从年轻代到老年代。(这里说一下:虚拟机给每个对象定义了一个对象年龄(Age)计数器。如果对象在 Eden 出生并经过第一次 Minor GC 后仍然存活,并且能被 Survivor 容纳的话,将被移动到 Survivor 空间中,并将对象年龄设为 1。对象在 Survivor 区中每熬过一次 Minor GC,年龄就增加 1 岁,当它的年龄增加到一定程度(默认为 15 岁)时,就会被晋升到老年代中。对象晋升老年代的年龄阈值,可以通过参数 -XX:MaxTenuringThreshold (阈值)来设置。)

Minor GC、Major GC与Full GC
7.随着minor GC的继续发生,对象将继续被推广到老一代的空间。
Minor GC、Major GC与Full GC
8.所以这几乎涵盖了与年轻一代的整个过程。 最终,一个Major GC将在老一代进行,清理和压缩这个空间。
Minor GC、Major GC与Full GC
写到这里,相信读者对Minor GC的全过程应该很了解了。
在这里提一个术语:Stop the World Event
截取官网一段原话:
Stop the World Event - All minor garbage collections are “Stop the World” events. This means that all application threads are stopped until the operation completes. Minor garbage collections are always Stop the World events.Major garbage collection are also Stop the World events. Often a major collection is much slower because it involves all live objects. So for Responsive applications, major garbage collections should be minimized. Also note, that the length of the Stop the World event for a major garbage collection is affected by the kind of garbage collector that is used for the old generation space.
所有的minor GC都是“stop the world”,这意味着 JVM 因为要执行GC而停止了应用程序的执行。当Stop-the-world发生时,除了GC所需的线程以外,所有线程都处于等待状态,直到GC任务完成。GC优化很多时候就是指减少Stop-the-world发生的时间。
MinGC\MajorGC都属于Stop-the-world, 那为什么MajorGC耗时较长呢?因为OldGen包含了大量幸存下来的对象。
下面说说MinorGC 和 FullGC
简单的讲:
Major GC 是清理OldGen。
Full GC 是清理整个堆空间—包括年轻代和永久代。
很不幸,实际上它还有点复杂且令人困惑。首先,许多 Major GC 是由 Minor GC 触发的,所以很多情况下将这两种 GC 分离是不太可能的。另一方面,许多现代垃圾收集机制会清理部分永久代空间,所以使用“cleaning”一词只是部分正确。
这使得我们不用去关心到底是叫 Major GC 还是 Full GC,大家应该关注当前的 GC 是否停止了所有应用程序的线程,还是能够并发的处理而不用停掉应用程序的线程。
通常当老年代满的时候会触发full GC,但可能还有其他情况。
老年代的垃圾回收策略:
老年代空间的GC事件基本上是在空间已满时发生,执行的过程根据GC类型不同而不同
JDK7一共有5种GC类型:
Serial GC
Parallel GC
Parallel Old GC (Parallel Compacting GC)
Concurrent Mark & Sweep GC (or “CMS”)
Garbage First (G1) GC
具体如何实现,我的另外一篇博文:http://blog.csdn.net/sky_100/article/details/70791886有介绍,感兴趣可以去看看。
说到这,不知道读者会不会想到一个问题,当发生一次Minor GC的时候,发现survivor区满了,怎么办?在这里,就引出了另一个问题,什么对象会进入老年代?经过查阅资料,发现出现这几种情况,对象会进入老年代:
1.当然是上面讲了当对象年龄到达临界值时,该临界值由参数:-XX:MaxTenuringThreshold来设置。
2.大对象直接进入老年代中。-XX:+PretenuerSizeThreshold 控制”大对象的“的大小。即当创建的对象大于这个临界值时,则该对象直接进入老年代。
3.动态对象年龄判定:虚拟机并不总是要求对象的年龄必须达到MaxTenuringThreshold才能晋升到老年代,如果在Survivor区中相同年龄(设年龄为age)的对象的所有大小之和超过Survivor空间的一半,年龄大于或等于该年龄(age)的对象就可以直接进入老年代,无需等到MaxTenuringThreshold中要求的年龄。
4.解决刚提出的问题,如果出现大量对象在minor gc后仍然存活的情况时,就需要老年代进行分配担保,让survivor无法容纳的对象直接进入老年代。
参考文章:
http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html