前端时间我们的服务器老收到报警短信,访问的时候又不慢(主要是7台服务器做了负载均衡,所以感觉不到问题),登录到服务器上看了下,GC出现了问题,
Java版本:
java version "1.6.0_32" Java(TM) SE Runtime Environment (build 1.6.0_32-b05) Java HotSpot(TM) 64-Bit Server VM (build 20.7-b02, mixed mode)
JVM参数:
-Xms16g -Xmx16g -Xmn2g -Xss1024K -XX:PermSize=256m -XX:MaxPermSize=512m -XX:ParallelGCThreads=8 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX:SurvivorRatio=4 -XX:MaxTenuringThreshold=10 -XX:CMSInitiatingOccupancyFraction=80
见图
一共有两个问题:
1)full gc提前了,我们设的是-XX:CMSInitiatingOccupancyFraction=80,当old区达到80%才进行一次cms gc,而现在25左右就开始了。
2)full gc时间过长,最近一次full gc花费了10几秒。
带着这两个问题进行排查:
用jstat查看最近一次full gc的原因,发现
导致频繁full gc的原来是System.gc(),在jvm参数里面添加-XX:+DisableExplicitGC,使用这个参数要防止NIO direct memory的OOM,可以观察服务器日志,当很长时间没有OOM,那就可以使用这个参数,不然可以用
-XX:+ExplicitGCInvokesConcurrent或 XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses,这两个参数也是用来改变System.gc()的默认行为用的;不同的是这两个参数只能配合CMS使用(-XX:+UseConcMarkSweepGC),而且System.gc()还是会触发GC的,只不过不是触发一个完全stop-the-world的full GC,而是一次并发GC周期。 CMS GC周期中也会做reference processing。
添加-XX:+DisableExplicitGC后,结果正常,可full gc的时间还是很长,观察GC日志,发现:
[1 CMS-remark: 10069518K(12582912K)] 12794124K(16078208K), 3.2904140 secs] [Times: user=22.29 sys=0.44, real=3.29 secs]
CMS-remark时间过长,添加-XX:+CMSScavengeBeforeRemark,这个参数是在CMS在做remark之前做一次YGC,最后问题终于解决,full gc时间只要100多毫秒。
不受报警短信的骚扰了。
相关推荐
- 增量压缩允许部分区域的压缩操作,而不是一次性对整个堆进行压缩,有助于降低GC停顿时间。 #### 四、数据区域与分配机制 ##### 1. 对象与堆 - **对象**:IBM JVM中的对象由类实例组成,每个对象都有自己的属性...
- **全量GC前**:默认情况下,在进行全量GC之前,会先进行一次新生代GC。 ##### 4.2 对象晋升机制 - **经历多次Minor GC后存活**:对象在经历多次Minor GC后仍然存活,则会被晋升到旧生代。 - **To Space空间不足*...
`-XX:CMSFullGCsBeforeCompaction=5`表示连续5次Full GC后进行一次压缩。 此外,`-XX:+UseCMSInitiatingOccupancyOnly`确保CMS始终使用指定的占用率阈值,而不是依赖HotSpot VM的自适应计算。`-XX:+UseParNewGC`和`...
JVM通过解析字节码使得Java代码能在任何安装了相应JVM的平台上执行,实现了"一次编写,到处运行"的理念。JVM的优化对于提升Java应用的性能至关重要,尤其是在处理大规模数据、高并发场景时。 在JVM优化实战中,首先...
- **Eden区与Survivor区**:新生代内存分为Eden区和两个Survivor区,大多数对象在Eden区创建,经历第一次 Minor GC 后,存活的对象会被移到Survivor区。 - **对象晋升**:当对象在Survivor区经历多次GC仍存活,会...
JVM的主要任务是解析字节码,并将其转化为机器语言,使得Java程序能够在不同的操作系统上无缝运行,实现了“一次编写,到处运行”的目标。理解JVM的工作原理,包括内存模型、类加载机制、垃圾回收(GC)等,对于优化...
"jvm-full-gc.zip"中的示例可能涵盖如何通过配置JVM参数来调整垃圾收集策略,以及如何分析和优化Full GC的性能。例如,通过设置`-XX:+PrintGCDetails`和`-XX:+PrintGCDateStamps`参数,可以输出详细的GC日志,以便...
大部分对象都会在Eden区分配,当Eden区满时,将触发一次Minor GC,存活的对象会被复制到其中一个Survivor区,另一个Survivor区被清空。 - **老年代**主要存放长时间存活的对象,当对象在Survivor区经过多次GC后仍然...
13. **-XX:CMSFullGCsBeforeCompaction**:设置运行多少次Full GC后对内存空间进行压缩、整理。 14. **-XX:CMSInitiatingOccupancyFraction**:设置启动CMS收集器的条件。 15. **-XX+UseCMSInitiatingOccupancyOnly*...
当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。 - **分代算法**: 根据对象的生命周期将内存划分为几块,如新生代、老年代。新生代采用复制算法,老年代采用...
- JVM实现了Java的跨平台特性,即“一次编写,到处运行”。 2. **类加载机制**: - 类的生命周期包括加载、验证、准备、初始化和卸载五个阶段。 - 双亲委派模型:类加载器在加载类时,会将任务委托给父类加载器...
JVM内存管理主要包括内存结构、内存分配以及垃圾回收(GC)等方面。了解这些知识对于优化Java应用程序的性能至关重要。 ### 1. JVM内存结构 #### 1.1.1 JVM内存概述 JVM内存分为几个关键区域,每个区域都有特定的...
它的主要任务是将编译后的Java类文件(.class文件)中的字节码转换为特定平台的机器码,实现了Java的“一次编写,到处运行”的跨平台特性。JVM由多个组件构成,包括类加载器、运行时数据区、执行引擎、本地方法接口...
当这一块的内存用完了,就将还存活着的对象复制到另一块上面,然后再把已使用过的内存空间一次清理掉。 - **标记-整理算法**:标记过程同标记-清除算法,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的...
它将Java字节码(.class文件)转换为特定平台的机器码,实现了跨平台的“一次编写,到处运行”特性。JVM主要由以下几个部分构成: 1. **类装载器(ClassLoader)**:负责加载类文件,分为引导类装载器、扩展类装载...
JVM通过解析字节码(.class文件)来执行程序,使得开发者无需关心底层操作系统细节,只需编写一次代码,就能在任何支持JVM的设备上运行。 JVM的主要组成部分包括类加载器、运行时数据区、执行引擎、本地方法接口和...
对象晋升到老年代的条件通常是:在Eden出生并经历一次Minor GC后存活,或者直接是大对象,或者年龄达到阈值(默认15),这可以通过-XX:MaxTenuringThreshold设置。 理解JVM内存管理和垃圾收集机制对于优化Java应用...
当线程被中断或恢复时,可以通过程序计数器找到上一次执行的位置。如果线程正在执行的是一个Java方法,则程序计数器记录的是当前字节码指令的地址;如果正在执行的是Native方法,则程序计数器的值为空。 2. **Java...
#### 一、JVM基本概念及组成部分 - **JVM内存区域划分**:JVM内存分为新生代、老年代以及元空间(Metaspace)三大区域。其中,新生代负责存放新创建的对象,经过多次垃圾回收后存活的对象将被移动至老年代;元空间则...
6. **持续监控**:调优并非一次性任务,应持续监控应用性能,随时进行微调。 总结,JVM参数调优和垃圾回收机制是Java性能优化的关键。掌握这些知识,开发者可以更好地理解应用的内存行为,有效提升系统的稳定性和...