标签:应用程序 推荐 cpu mon hang 对象 heap 模式 top
Java 堆内存被划分为新生代和老年代两部分,因此 JVM 通常采用分代回收算法。新生代主要使用复制和标记-清除垃圾回收算法 ,老年代主要使用标记-整理垃圾回收算法。JVM 中针对新生代和年老代分别提供了多种不同的垃圾收集器。
根据线程特点,可以将收集器分为三类:
// 串行收集器开启方式
-XX:+UseSerialGC
// 并行收集器开启方式
-XX:+UseSerialGC
// CMS 收集器开启方式
-XX:+UseParNewGC -XX:+UseConcMarkSweepGC
// G1 收集器开启方式
-XX:+UseG1GC
新生代 Parallel Scavenge 收集器与 ParNew 收集器工作原理类似:
- 都是多线程的收集器;
- 都使用的是复制算法;
- 在垃圾收集过程中都需要暂停所有的工作线程。
新生代 Serial 与年老代 Serial Old 搭配垃圾收集过程图:
新生代 Parallel Scavenge 收集器与 ParNew 收集器工作原理类似,都是多线程的收集器,都使用的是复制算法,在垃圾收集过程中都需要暂停所有的工作线程。新生代 Parallel Scavenge/ParNew 与年老代 Serial Old 搭配垃圾收集过程图:
在 JDK1.6 之前,新生代使用 ParallelScavenge 收集器只能搭配年老代的 Serial Old 收集器,只能保证新生代的吞吐量优先,无法保证整体的吞吐量,Parallel Old 正是为了在年老代同样提供吞吐量优先的垃圾收集器,如果系统对吞吐量要求比较高,可以优先考虑新生代 Parallel Scavenge和年老代 Parallel Old 收集器的搭配策略。
新生代 Parallel Scavenge 和年老代 Parallel Old 收集器搭配运行过程图:
CMS 运行过程分为以下 4 个阶段:
由于耗时最长的并发标记和并发清除过程中,垃圾收集线程可以和用户现在一起并发工作,所以总体上来看CMS 收集器的内存回收和用户线程是一起并发地执行。
新生代区域:G1 收集器中新生代的垃圾收集依然采用暂停所有应用线程的方式,将存活对象拷贝到老年代或者 Survivor 空间;
老年代区域:G1 收集器通过将对象从一个区域复制到另外一个区域,以此来完成老年代的清理工作;
Humongous区域:巨型对象区域。如果一个对象占用的空间超过了分区容量 50% 以上,G1 收集器就认为这是一个巨型对象。这些巨型对象,默认直接会被分配在年老代,但是如果它是一个短期存在的巨型对象,就会对垃圾收集器造成负面影响。为了解决这个问题,G1 划分了一个 Humongous 区,它用来专门存放巨型对象。如果一个 H 区装不下一个巨型对象,那么 G1 会寻找连续的 H 分区来存储。为了能找到连续的 H 区,有时候不得不启动 Full GC。
说起大对象的分配,我们不得不谈谈对象的分配策略。它分为3个阶段:
TLAB为线程本地分配缓冲区,它的目的为了使对象尽可能快的分配出来。如果对象在一个共享的空间中分配,我们需要采用一些同步机制来管理这些空间内的空闲空间指针。在Eden空间中,每一个线程都有一个固定的分区用于分配对象,即一个TLAB。分配对象时,线程之间不再需要进行任何的同步。
对TLAB空间中无法分配的对象,JVM会尝试在Eden空间中进行分配。如果Eden空间无法容纳该对象,就只能在老年代中进行分配空间。
最后,G1提供了两种GC模式,Young GC和Mixed GC,两种都是Stop The World(STW)的。下面我们将分别介绍一下这2种模式。
Young GC 主要是对 Eden 区进行 GC ,它在 Eden 空间耗尽时会被触发。在这种情况下,Eden 空间的数据移动到 Survivor 空间中,如果 Survivor 空间不够,Eden 空间的部分数据会直接晋升到年老代空间。Survivor 区的数据移动到新的 Survivor 区中,也有部分数据晋升到老年代空间中。最终 Eden 空间的数据为空,GC 停止工作,应用线程继续执行。
Mix GC不仅进行正常的新生代垃圾收集,同时也回收部分后台扫描线程标记的老年代分区。
全局并发标记(global concurrent marking)
1.1 初始标记(initial mark,STW):在此阶段,G1 GC 对根进行标记。该阶段与常规的 (STW) 年轻代垃圾回收密切相关;
1.2 根区域扫描(root region scan):G1 GC 在初始标记的存活区扫描对老年代的引用,并标记被引用的对象。该阶段与应用程序(非 STW)同时运行,并且只有完成该阶段后,才能开始下一次 STW 年轻代垃圾回收;
1.3. 并发标记(Concurrent Marking):G1 GC 在整个堆中查找可访问的(存活的)对象。该阶段与应用程序同时运行,可以被 STW 年轻代垃圾回收中断;
1.4 最终标记(Remark,STW): 该阶段是 STW 回收,帮助完成标记周期。G1 GC 清空 SATB 缓冲区,跟踪未被访问的存活对象,并执行引用处理;
1.5. 清除垃圾(Cleanup,STW):在这个最后阶段,G1 GC 执行统计和 RSet 净化的 STW 操作。在统计期间,G1 GC 会识别完全空闲的区域和可供进行混合垃圾回收的区域。清理阶段在将空白区域重置并返回到空闲列表时为部分并发。
拷贝存活对象(evacuation)
G1 收集器与 CMS 收集器相比,G1 收集器两个最突出的改进是:
- 基于标记-整理算法,不产生内存碎片;
- 可以非常精确控制停顿时间,在不牺牲吞吐量前提下,实现低停顿垃圾回收。
// G1 收集器参数设置
-XX:+UseG1GC -Xmx32g -XX:MaxGCPauseMillis=200
// -XX:+UseG1GC —— 为开启G1垃圾收集器,
// -Xmx32g —— 设计堆内存的最大内存为32G,
// -XX:MaxGCPauseMillis=200 —— 设置GC的最大暂停时间为200ms
标签:应用程序 推荐 cpu mon hang 对象 heap 模式 top
原文地址:https://www.cnblogs.com/weechang/p/12493158.html