Minor GC、Major GC和Full GC之间的区别

文章要求读者熟悉 JVM 内置的通用垃圾回收原则。堆内存划分为 Eden、Survivor 和 Tenured/Old 空间,代假设和其余不一样的 GC 算法超出了本文讨论的范围。 html

minor-gc-major-gc-full-gc


Minor GC

从年 轻代空间(包括 Eden 和 Survivor 区域)回收内存被称为 Minor GC。这必定义既清晰又易于理解。可是,当发生Minor GC事件的时候,有一些有趣的地方须要注意到: java

  1. 当 JVM 没法为一个新的对象分配空间时会触发 Minor GC,好比当 Eden 区满了。因此分配率越高,越频繁执行 Minor GC。
  2. 内存池被填满的时候,其中的内容所有会被复制,指针会从0开始跟踪空闲内存。Eden 和 Survivor 区进行了标记和复制操做,取代了经典的标记、扫描、压缩、清理操做。因此 Eden 和 Survivor 区不存在内存碎片。写指针老是停留在所使用内存池的顶部。
  3. 执行 Minor GC 操做时,不会影响到永久代。从永久代到年轻代的引用被当成 GC roots,从年轻代到永久代的引用在标记阶段被直接忽略掉。
  4. 质疑常规的认知,全部的 Minor GC 都会触发“全世界的暂停(stop-the-world)”,中止应用程序的线程。对于大部分应用程序,停顿致使的延迟都是能够忽略不计的。其中的真相就 是,大部分 Eden 区中的对象都能被认为是垃圾,永远也不会被复制到 Survivor 区或者老年代空间。若是正好相反,Eden 区大部分新生对象不符合 GC 条件,Minor GC 执行时暂停的时间将会长不少。

因此 Minor GC 的状况就至关清楚了——每次 Minor GC 会清理年轻代的内存 算法

Major GC vs Full GC

你们应该注意到,目前,这些术语不管是在 JVM 规范仍是在垃圾收集研究论文中都没有正式的定义。可是咱们一看就知道这些在咱们已经知道的基础之上作出的定义是正确的,Minor GC 清理年轻带内存应该被设计得简单: 并发

  • Major GC 是清理永久代。
  • Full GC 是清理整个堆空间—包括年轻代和永久代。

很不幸,实际上它还有点复杂且使人困惑。首先,许多 Major GC 是由 Minor GC 触发的,因此不少状况下将这两种 GC 分离是不太可能的。另外一方面,许多现代垃圾收集机制会清理部分永久代空间,因此使用“cleaning”一词只是部分正确。 工具

这使得咱们不用去关心究竟是叫 Major GC 仍是 Full GC,你们应该关注当前的 GC 是否中止了全部应用程序的线程,仍是可以并发的处理而不用停掉应用程序的线程spa

这种混乱甚至内置到 JVM 标准工具。下面一个例子很好的解释了个人意思。让咱们比较两个不一样的工具 Concurrent Mark 和 Sweep collector (-XX:+UseConcMarkSweepGC)在 JVM 中运行时输出的跟踪记录。 线程

考虑到这种状况,最好避免以 Minor、Major、Full GC 这种方式来思考问题。而应该监控应用延迟或者吞吐量,而后将 GC 事件和结果联系起来。 翻译

随着这些 GC 事件的发生,你须要额外的关注某些信息,GC 事件是强制全部应用程序线程中止了仍是并行的处理了部分事件。 设计



原文连接: javacodegeeks 翻译: ImportNew.com 光光头去打酱油 指针

译文连接:  http://www.importnew.com/15820.html
相关文章
相关标签/搜索