文章目录
-
- 调优案例
-
- 案例1:应对高并发、短生命周期对象的应用
- [案例2:防止频繁Full GC导致延迟](#案例2:防止频繁Full GC导致延迟)
- 案例3:优化服务响应时间,减少停顿时间
- 案例4:监控和诊断内存泄露
- 一些参数
基于JDK1.8
调优案例
下面是一些结合实际应用场景的JVM调优参数及其作用的解释:
案例1:应对高并发、短生命周期对象的应用
假设我们正在优化一个高并发且产生大量短生命周期对象的服务,例如Web服务器或高性能计算环境,其中大部分对象在短时间内就会变成无用对象。
-
参数设置:
bash-Xms4g -Xmx4g -Xmn2g -XX:SurvivorRatio=8 -XX:+UseParallelGC -XX:MaxTenuringThreshold=15
-
参数解析:
-Xms4g -Xmx4g
:设置堆内存大小初始化和最大值均为4GB,保证程序有足够的内存空间,并消除内存自动扩展带来的额外开销。-Xmn2g
:设置年轻代大小为2GB,由于大量临时对象主要在年轻代中分配和回收,较大的年轻代可以容纳更多短生命周期的对象,减少年轻代GC频率。-XX:SurvivorRatio=8
:设置Eden区与Survivor区的比例为8:1,增加Eden区的空间,有利于容纳更多的新创建对象,减少晋升到老年代的机会。-XX:+UseParallelGC
:启用并行垃圾收集器(Parallel GC),利用多核处理器的优势,加快年轻代GC的速度。-XX:MaxTenuringThreshold=15
:设置对象在年轻代中经历的GC次数阈值,较高的值意味着对象有更多机会在年轻代内就被回收,降低老年代的压力。
案例2:防止频繁Full GC导致延迟
在一个大型企业级应用中,发现系统频繁触发Full GC,影响了整体响应速度。
-
参数设置:
bash-Xms16g -Xmx16g -XX:NewRatio=3 -XX:MaxMetaspaceSize=512m -XX:+UseG1GC -XX:InitiatingHeapOccupancyPercent=70
-
参数解析:
-Xms16g -Xmx16g
:确保足够的内存容量,并避免堆大小变化带来的系统抖动。-XX:NewRatio=3
:年轻代与老年代的大小比例为1:3,可以根据长期存活对象的比例调整这一参数,减少老年代满载导致的Full GC。-XX:MaxMetaspaceSize=512m
:限制元空间大小,防止类元数据过多引起的OOM错误。-XX:+UseG1GC
:采用G1垃圾收集器,它能够预测并避免长时间暂停,尤其适用于大型堆且要求低延迟的应用。-XX:InitiatingHeapOccupancyPercent=70
:对于G1来说,设置初始标记开始时堆占用率的阈值,当达到这个百分比时触发并发标记周期,通过提前回收避免堆积过多垃圾而引发更耗时的Full GC。
案例3:优化服务响应时间,减少停顿时间
假设我们有一个在线交易系统,对响应时间和稳定性要求极高,希望尽量减少因GC造成的系统暂停时间。
-
参数设置:
bash-Xms32g -Xmx32g -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:InitiatingHeapOccupancyPercent=45 -XX:ParallelGCThreads=8 -XX:ConcGCThreads=4 -XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=60 -XX:G1HeapRegionSize=32m -XX:+UnlockExperimentalVMOptions -XX:G1MixedGCLiveThresholdPercent=65 -XX:+UseStringDeduplication
-
参数解析:
-Xms32g -Xmx32g
:设置堆内存大小,确保有足够的内存满足系统需求,避免内存大小的变化导致额外的性能损失。-XX:+UseG1GC
:选择G1垃圾收集器,它具备低延迟的特性,特别适合对响应时间敏感的应用场景。-XX:MaxGCPauseMillis=200
:设置G1目标的最大暂停时间,力求减小垃圾回收对应用的影响。-XX:InitiatingHeapOccupancyPercent=45
:设置触发并发标记周期的Java堆占用率阈值,早起启动回收可以预防长时间GC。-XX:ParallelGCThreads=8 -XX:ConcGCThreads=4
:分别设置并行垃圾回收线程数和并发标记线程数,根据系统CPU核心数适当调整。-XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=60
:限制年轻代大小范围,使得G1可以灵活调整年轻代大小以适应应用负载。-XX:G1HeapRegionSize=32m
:设置G1堆分区大小,依据应用的内存分配特征和机器内存大小合理设置。-XX:+UnlockExperimentalVMOptions -XX:G1MixedGCLiveThresholdPercent=65
:解锁实验性VM选项,并设置混合集合的存活对象阈值,调整混合集合的执行时机,降低停顿时间。-XX:+UseStringDeduplication
:启用字符串去重功能,减少字符串对象在内存中的重复存储,有效节约内存空间。
案例4:监控和诊断内存泄露
在某大数据处理应用中,发现系统随着时间推移内存占用不断增长,疑似存在内存泄露问题。
-
参数设置:
bash-Xmx64g -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/data/dumps/java_heapdump.hprof -XX:+UseConcMarkSweepGC -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -XX:+PrintGCCause -XX:+PrintReferenceGC -XX:+PrintAdaptiveSizePolicy -XX:+UnlockDiagnosticVMOptions -XX:NativeMemoryTracking=summary -XX:+TraceClassLoading -XX:+TraceClassUnloading
-
参数解析:
-Xmx64g
:设置最大堆内存大小,确保系统有足够的内存运行。-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/data/dumps/java_heapdump.hprof
:在发生OOM异常时生成堆转储文件,便于后续分析内存泄露。-XX:+UseConcMarkSweepGC
:选择CMS垃圾收集器,因为该场景下,稳定性和延迟可能不如防止内存泄露重要。-XX:+PrintGCDetails
等GC日志参数:开启详细GC日志,帮助追踪内存分配和回收情况。-XX:+UnlockDiagnosticVMOptions -XX:NativeMemoryTracking=summary
:解锁诊断VM选项并开启原生内存跟踪,分析非Java堆内存的使用情况。-XX:+TraceClassLoading -XX:+TraceClassUnloading
:追踪类加载和卸载,有助于排查是否有类加载泄露的问题。
一些参数
堆内存大小
-
-Xms
:设定Java虚拟机初始堆内存大小,默认值由JVM自行决定。 -
-Xmx
:设定Java虚拟机最大堆内存大小。 -
-Xmn
:设置年轻代(Young Generation)的初始大小和最大大小。这个值通常作为整个堆的一部分来设置。 -
分配年轻代空间的比例(相对于整个堆):
-XX:NewRatio=
:设置年轻代与老年代(Old Generation)的比例。例如,如果设为3,则年轻代与老年代的大小比例为1:3。 -
Survivor空间的策略:
-XX:+UseAdaptiveSizePolicy
:启用自适应大小策略,JVM会根据应用的行为动态调整年轻代和其他内存区域的大小。 -
控制晋升至老年代的对象年龄阈值:
-XX:MaxTenuringThreshold=<value>
:设置对象从年轻代晋升到老年代的最大年龄(即经历多少次Minor GC)。默认值通常是由JVM决定的,也可以手动设置。
-
并发标记扫描(CMS)或Garbage First(G1)垃圾收集器特有的年轻代相关参数也会有所不同,但上述参数通常是通用的。
举例来说,配置年轻代占总堆大小的1/3且Survivor区与Eden区比为2:8的设置方式可能是:
bash
-Xms1g -Xmx1g -Xmn300m -XX:SurvivorRatio=2
这将启动一个总堆大小为1GB的JVM实例,其中年轻代大小固定为300MB,
Survivor区和Eden区按两个Survivor区各占总年轻代大小的1/10,
Eden区占8/10进行划分。
元空间大小
-XX:MetaspaceSize
:元空间初始大小,在JDK1.8中替代了PermGen空间,用于存储类的元数据。-XX:MaxMetaspaceSize
:元空间的最大大小。
垃圾收集器相关参数
-XX:+UseG1GC
:启用G1垃圾收集器。-XX:+UseParallelGC
:启用并行垃圾收集器(年轻代)。-XX:+UseConcMarkSweepGC
:启用CMS垃圾收集器(老年代)。-XX:NewRatio
:年轻代与老年代的内存比例。-XX:SurvivorRatio
:Eden区与Survivor区的比例。
垃圾收集行为控制
-XX:MaxTenuringThreshold
:对象晋升到老年代之前经历的垃圾回收次数阈值。-XX:InitiatingHeapOccupancyPercent
(G1 GC):触发并发标记周期的堆占用率阈值。
内存区域细分(G1收集器特定)
-XX:G1HeapRegionSize
:设置G1堆区域的大小。
GC
-
-XX:+UseParallelGC
:启用并行新生代收集器,使用多个线程进行垃圾回收。 -
-XX:ParallelGCThreads
:设置并行收集器工作的线程数。 -
-Xloggc:filename
:指定GC日志文件路径。 -
-XX:+PrintGCDetails
:打印详细的GC处理信息。 -
-XX:+PrintGCDateStamps
:在GC日志中添加时间戳。 -
-XX:NumberOfGCLogFiles
和-XX:GCLogFileSize
:分别用于设置GC日志文件的数量和单个文件大小(滚动日志)。
栈内存大小
-Xss
:每个线程的栈内存大小。
直接内存大小
-XX:MaxDirectMemorySize
:设置可以使用的直接内存大小。
其他调优选项
-XX:+DisableExplicitGC
:禁止程序主动调用System.gc()。-XX:+AggressiveOpts
:开启激进优化策略。-XX:TargetSurvivorRatio
:G1 GC的目标幸存者区占用率。
监控工具:
jstat -gccause :查看实时GC统计信息,包括引起Full GC的原因。
jinfo:动态获取或修改运行中的Java进程的JVM参数。
jmap:生成堆转储快照,用于离线分析。
jconsole 或 VisualVM:图形化监控工具,可以实时观察GC活动。