现象:
jstat -gcutil pid 1000观察到的情况,段时间内连续两次full gc
S0 S1 E O P YGC YGCT FGC FGCT GCT 59.33 0.00 63.98 69.66 59.31 24338 274.969 307 17.349 292.318 59.33 0.00 86.19 69.66 59.31 24338 274.969 307 17.349 292.318 0.00 60.52 10.22 70.10 59.31 24339 275.006 308 17.373 292.379 0.00 60.52 30.03 70.10 59.31 24339 275.006 308 17.373 292.379 0.00 60.52 53.57 70.10 59.31 24339 275.006 308 17.373 292.379 0.00 60.52 76.45 70.10 59.31 24339 275.006 308 17.373 292.379 0.00 60.52 93.77 70.10 59.31 24339 275.006 308 17.373 292.379 61.16 0.00 15.66 70.53 59.31 24340 275.040 308 17.373 292.413 61.16 0.00 40.71 67.96 59.31 24340 275.040 309 17.399 292.439 61.16 0.00 66.44 59.90 59.31 24340 275.040 309 17.399 292.439
同一时间的gc log
第一次
[GC [1 CMS-initial-mark: 1220647K(1740800K)] 1227199K(2385920K), 0.0057570 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
在旧生代空间为1220647K触发marking操作,后面1227199K(2385920K)=当前总体jvm内存使用(maxMem)
initial 标记从根集合中可直接访问的对象,要停顿整个应用
原文:This is initial Marking phase of CMS where all the objects directly reachable from roots are marked and this is done with all the mutator threads stopped.
[CMS-concurrent-mark: 1.084/1.084 secs] [Times: user=2.43 sys=0.11, real=1.08 secs]
完成mark耗时1.084 secs 并发执行
[CMS-concurrent-preclean: 0.008/0.009 secs] [Times: user=0.01 sys=0.00, real=0.01 secs]
开始执行清理,目的是减少remark的时间
第二次
[GC [ParNew: 579913K->4387K(645120K), 0.0080390 secs] 1800561K->1226923K(2385920K), 0.0082860 secs] [Times: user=0.05 sys=0.00, real=0.01 secs]
minor gc
CMS: abort preclean due to time [CMS-concurrent-abortable-preclean: 2.715/5.047 secs] [Times: user=4.42 sys=0.40, real=5.05 secs]
停止执行preclean 默认是eden到达50%或者real time=5secs停止
[GC[YG occupancy: 153139 K (645120 K)][Rescan (parallel) , 0.0348570 secs][weak refs processing, 0.0005070 secs] [1 CMS-remark: 1222535K(1740800K)] 1375675K(2385920K), 0.0355150 secs] [Times: user=0.19 sys=0.00, real=0.04 secs]
remark会停顿整个应用
[CMS-concurrent-sweep: 1.358/1.360 secs] [Times: user=1.85 sys=0.10, real=1.36 secs]
[CMS-concurrent-reset: 0.003/0.003 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
gcutil 看到连续两次 full gc
原因分析:
目前来看,只有当initial-mark和remark时才会停顿整个应用,这个两个时间点jstat -gcutil表现都为full gc次数加一
real != user+sys
原因:user和sys代表处于用户和系统态的时间,不包含block的时间.但是由于多cpus这个东东是累加的.所以一般来说user和sys相加都大于real
real是从启动到终止的真实时间(现实中消耗),包含block.
----
CMS-initial-mark 对应一次fullgc,会停顿所有线程
CMS-remark 对应依次fullgc,会停顿所有线程
其他的日志对应的操作都是不会停顿线程的
可以通过grep "initial" 和grep "remark" 来看你每次停顿的时间
相关推荐
在Java世界中,JVM(Java虚拟机)是运行所有Java应用程序的核心,它负责解析字节码、管理内存以及执行线程。本教程——“深入JVM内核—原理、诊断与优化视频教程”着重讲解了JVM的内部机制,特别是关于垃圾收集...
此外,监控GC日志,分析GC行为,以及使用适当的GC算法(如CMS、G1或ZGC)也是优化过程中的关键步骤。通过这些实践,开发者能够确保Java应用程序在运行时具有良好的内存管理和高效的资源利用率。
当老年代空间不足或系统请求Full GC时,会执行此操作。Full GC开销大,应尽量避免频繁触发。 3. 垃圾收集器 - Serial GC:单线程的垃圾收集器,适合小型应用。 - Parallel GC:多线程版本的Serial GC,提高了吞吐...
1. **对象分配**:当程序创建一个新的对象时,JVM会在堆内存中为这个对象分配空间。通常,新生代(Young Generation)是对象首选的分配区域,尤其是Eden区。 2. **垃圾识别**:GC通过一系列算法来判断哪些对象是...
针对不同区域,JVM提供了多种GC算法,如Serial、Parallel、CMS、G1等,每种算法有其适用场景和优缺点。 1. **VisualVM**:这是一款集成的Java性能分析工具,可以显示JVM的实时状态,包括类加载、线程、CPU、内存和...
然而,CMS在内存压力过大时,可能会出现“Concurrent Mode Failure”(并发模式失败)问题,此时GC需要暂停应用进行“预清理”,以避免在并发标记阶段因空间不足而被迫暂停应用。为了避免这种情况,可以通过调整`-XX...
大部分对象在Eden区被创建,经过一次GC后,存活的对象会被移到Survivor区,然后再经过几次GC仍然存活的对象会被晋升到老年代。 2. **老年代(Tenured Generation)**:老年代用于存储生命周期较长的对象。当新生代...
- **新生代和老年代**:Java堆被划分为新生代(Eden和两个Survivor区)和老年代,不同的GC算法针对这两个区域进行优化。 3. **垃圾收集器** - **Serial GC**:单线程的收集器,适合小型应用和服务器启动时使用。 ...
CMS提供了一些参数来优化其行为,比如`UseCMSCompactAtFullCollection`用于在Full GC时进行内存碎片整理,以及`CMSFullGCsBeforeCompaction`来控制每隔多少次不压缩的Full GC后执行一次带压缩的Full GC。 然而,CMS...
- 复制算法:将内存分为两部分,每次只使用一部分,当这部分满时,将存活对象复制到另一部分,然后清空。该算法解决了碎片问题,但内存利用率低。 - 标记-整理算法:标记后,将存活对象移动到一端,直接清理另一端...
4. **垃圾收集**:JVM提供了多种GC算法,如Serial、ParNew、Parallel Scavenge、CMS、G1和ZGC等,它们各有优缺点,适用于不同场景。 **GC详解** 1. **GC目标**:GC的主要目标是高效地回收内存,减少停顿时间,并...
通过VisualGC,你可以观察到不同GC算法(如Serial、Parallel、CMS、G1等)下的GC活动,包括GC事件的发生频率、耗时、内存区域的变化等。 VisualVM还提供了以下关键功能: 1. **线程分析**:查看并分析应用程序中的...
Java提供了多种GC算法,如Serial GC、Parallel GC、Parallel Old GC、CMS(Concurrent Mark Sweep)和G1(Garbage-First)GC。每种算法在吞吐量、响应时间、停顿时间等方面有不同的权衡。 Serial GC适用于单CPU环境...
- 新创建的对象首先在Eden空间分配,经过一次或多次GC后仍然存活的对象会被转移到Survivor空间或老年代。 - 这种设计基于观察结果:大多数对象很快就会死亡,只有少数会长期存活。 2. **GC类型** - Minor GC:...
3. **监控和分析**:使用JVisualVM、Visual GC等工具监控应用运行时的GC行为,通过分析GC日志来确定最佳配置。例如,频繁的Full GC可能是由于对象存活时间过长导致,可以通过调整年轻代大小或采用更合适的垃圾回收...
1. **日志解析**:GCViewer能够解析各种格式的GC日志,包括Sun/Oracle JVM、IBM JVM以及OpenJ9等产生的日志,支持G1、Parallel、CMS、Serial等多种GC算法的日志。 2. **实时可视化**:工具将日志中的数据转化为实时...
GC主要包括新生代GC(Minor GC)、老年代GC(Major GC)和全堆GC(Full GC)。 - **新生代GC**:主要针对新生代中的Eden区和两个Survivor区。当Eden区满时,会触发Minor GC,将存活的对象复制到Survivor区,无法...
- **调优参数**:例如`-Xms`、`-Xmx`设定堆大小,`-XX:NewRatio`设置年轻代与老年代比例,`-XX:+UseConcMarkSweepGC`选择特定的GC算法。 - **性能指标**:关注吞吐量、响应时间、暂停时间等,根据应用需求平衡这些...
当新生代(Eden + 一个Survivor区)在Minor GC后仍无法容纳存活对象时,这些对象会被晋升到老年代。如果老年代空间不足,JVM会触发Full GC。 ### **垃圾收集器** 1. **Serial收集器**:单线程,适用于小型应用或...