JVM参数与性能调优
本文主要适用于HotSpot JVM的参数设置与调优。
工具类型 | 说明 |
堆Dump分析 | 推荐使用MAT,参考使用Eclipse Memory Analyzer分析JVM堆Dump |
栈Dump分析 | 推荐使用在线工具:http://fastthread.io/ |
低成本剖析 | 推荐使用JMC,参考使用Oracle Java Mission Control监控JVM运行状态 |
命令 | 说明 | ||
jps |
JVM Process Status Tool,显示指定系统内所有的HotSpot虚拟机进程 格式: 选项: |
||
jstat |
JVM Statistics Monitoring Tool,用干收集HotSpot虚拟机各方面的运行数据(类装载、内存、垃圾收集、JIT编译等) 格式: 选项: 举例:
|
||
jinfo |
Configuration Info for Java,实时地査看和调整虚拟机的各项参数。 格式: 举例:
|
||
jmap |
Memory Map for Java,生成虚拟机的内存转储快照(heapdump文件) 格式: 选项: 举例:
|
||
jhat |
JVM Heap Dump Browser,用于分析 heapdump 文件,它会建立一个 HTTP/HTML 服务器,让用户可以在浏览器上査看分析结果 注意JVM内部的类型表示方式。 |
||
jstack |
Stack Trace for Java,显示虚拟机的线程快照 格式: 选项: |
||
jcmd |
不带任何参数运行jcmd,显示所有JVM进程的PID和Main类名 运行 jcmd 0 help,显示每个JVM支持的命令 命令示例:
|
1 2 3 4 5 6 7 8 |
# options:JVM参数 # class:main方法所在类 java [ options ] class [ arguments ] # -jar 被调用的jar包路径 java [ options ] -jar file.jar [ arguments ] #用于GUI javaw [ options ] class [ arguments ] javaw [ options ] -jar file.jar [ arguments ] |
参数 | 说明 |
-client | 使用 Java HotSpot Client VM,64bit的JDK忽略此选项,使用-server |
-server | 使用Java HotSpot Server VM,64bit的JDK只能是这种模式,不需要指定 |
-agentlib:libname[=options] |
根据名称加载本地(native)JVM代理,例如: -agentlib:hprof |
-agentpath:pathname[=options] |
根据路径全名加载本地JVM代理,例如: -agentpath:D:\JavaEE\jprofiler\7.2.2\bin\windows-x64\jprofilerti.dll=offline |
-classpath classpath |
指定一系列分号;分隔的目录、JAR、ZIP文件路径,用于从中寻找类文件,注意,此参数覆盖CLASSPATH环境变量。如果没指定,也没有CLASSPATH环境变量,当前目录(.)为类路径 |
-Dproperty=value | 设置JVM系统属性 |
-da[:pkgname | :clsname ] |
禁用断言,默认是禁用的 |
-ea[:pkgname | :clsname ] |
启用断言:例如: -ea:cc.gmem.demo... ,启用demo包及其子包的断言 |
-esa,-dsa | 启用、禁用所有system classes的断言 |
-help -? | 显示帮助 |
-jar | 执行包装在jar中的类 |
-javaagent:jarpath[=options] |
加载基于Java语言的JVM代理 |
-splash:imagepath | 显示启动画面 |
-verbose:class -verbose:gc -verbose:jni |
显示类加载信息 显示垃圾回收信息 显示JNI接口活动信息 |
-version -showversion |
显示版本信息并退出 |
参数 | 说明 |
-X | 显示非标准参数并退出 |
-Xint | 以解释模式运行,字节码不会编译成native代码 |
-Xbatch | 禁止后台编译,默认情况下,后台编译字节码,编译完成前,解释执行,禁止后,必须编译完毕后才能执行方法 |
-Xbootclasspath:bootclasspath | 设置boot class的寻找路径(JAR、ZIP或者目录) |
-Xbootclasspath/a:path | 附加boot class的寻找路径 |
-Xbootclasspath/p:path | 前缀boot class的寻找路径 |
-Xcheck:jni | 检查JNI函数的调用,比如验证参数有效性,如果失败,则退出JVM |
-Xfuture | 进行严格的字节码格式检查 |
-Xnoclassgc | 禁止类的垃圾回收 |
-Xincgc | 启用增量的垃圾回收,默认禁用,减少垃圾回收导致的长时间系统停顿,但是会时时工作,影响程序效率 |
-Xloggc:file | 记录垃圾回收的每个事件 |
-XX:AllocationPrefetchStyle=n | 设置内存分配预读取风格,默认2 |
-XX:+|-DisableAttachMechanism | 设置类似jmap、jconsole之类的命令是否可以附到(attach)到运行中的JVM,默认这个特性是禁用的 |
-XX:+UnlockCommercialFeatures | 解锁商业特性 |
-XX:+|-FlightRecorder | 商业特性。启用黑匣子功能 |
-XX:FlightRecorderOptions |
配置黑匣子的选项,包括: defaultrecording=true|false 黑匣子是持续运行,还是运行限定的时间,默认false |
-XX:StartFlightRecording |
启动黑匣子 compress=true|false 是否压缩黑匣子日志文件 |
参数与默认值 |
说明 |
-XX:-AllowUserSignalHandlers |
允许用户定义的信号处理器(Solaris/Linux) |
-XX:AltStackSize=16384 |
备选信号栈大小(Solaris,5.0-) |
-XX:+FailOverToOldVerifier |
如果验证失败,使用旧版本的验证启(6.0+) |
-XX:PreBlockSpin=10 |
-XX:+UseSpinning使用的自旋计数器,进入系统线程同步代码前,自旋的次数 (1.4.2+) |
-XX:-RelaxAccessControlCheck |
放松验证器的访问控制检查 ( 6.0+) |
-XX:-UseSpinning |
进入系统同步化代码前,在Java监视器上启用native自旋( 1.4.2 and 5.0 ) |
-XX:+UseThreadPriorities |
使用系统native的线程优先级 |
参数与默认值 |
说明 |
-XssN |
设置线程栈大小。JDK5.0+为1M,以前为256K。减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数限制在3000~5000左右 |
-XmsN | 设置初始内存大小(字节),必须是1024的倍数、大于1MB,可以后缀k/K、m/M、g/G |
-XmxN | 设置最大内存大小(字节),必须是1024的倍数、大于2MB,可以后缀k/K、m/M、g/G |
-XX:PermSize | 设置永久代初始占用内存大小 |
-XX:MaxPermSize=64m |
设置永久代最大占用内存大小 |
-XmnN | 年轻代的内存大小(Eden区+2个Survivor区) |
-XX:NewRatio=2 | 年老代/年轻代占用空间比率 |
-XX:SurvivorRatio=8 | 年轻代Eden/Survivor区域尺寸比例,默认8:1。通常有2个Survivor区,因此8:1意味着Survivor总大小为2 |
-XX:PretenureSizeThreshold | 用于ParNew、Serial。大于此值(字节)的对象将在年老代直接分配,避免在Eden区及Survivor区之间发生大量的内存拷贝 |
-XX:MaxTenuringThreshold |
设置对象进入年老代前,在Survivor区复制(活过Minor GC)的最大次数,默认情况下,JVM会动态调整TenuringThreshold值。 此值设置过大,则ParNew分析Survivor区对象关系时可能消耗时间过大,影响性能。 如果Survivor满了,对象会强制复制到年老代 |
-XX:TargetSurvivorRatio=50 |
JVM会试图调整TenuringThreshold期望下次Minor GC后Survivor的From区的使用量能接近50 如果设置为100,相当于禁止调整TenuringThreshold |
-XX:+UseTLAB |
启用线程本地分配缓冲(Thread local allocation buffers)。启用TLAB后,只有TLAB被用满了,才会尝试到Eden区域申请内存 |
-XX:TLABSize=n |
TLAB的大小 |
-XX:+ResizeTLAB |
是否可以动态修改TLAB大小 |
-XX:MaxGCPauseMillis=n |
设置GC暂停时间目标。如果无法达到要求,JVM会自动调整年轻代大小 |
-XX:GCTimeRatio=n |
控制吞吐量,设置垃圾回收时间占程序运行时间的百分比,公式为1/(1+n) |
-XX:+UseSerialGC |
使用串行垃圾回收 (5.0+) |
-XX:+UseG1GC |
启用G1垃圾回收器 |
-XX:+UseParallelGC |
吞吐量收集器。Parallel scavenge collector,对年轻代使用并行垃圾回收(1.4.1+),不能与CMS收集器同时使用。算法针对多CPU大内存(例如10G+)进行了优化,致力于在尽量减少停顿的同时最大化吞吐量 |
-XX:+UseParallelOldGC |
吞吐量收集器。在使用-XX:+UseParallelGC时,对年老代使用并行垃圾回收(5.0u6) |
-XX:+UseParNewGC |
Parallel copying collector,对年轻代使用并行垃圾回收,可与CMS收集器(-XX:+UseConcMarkSweepGC)同时使用。JDK5.0以上,JVM会根据系统配置自行设置。工作方式类似于原始的复制算法,但是使用多个线程进行并行的拷贝 |
-XX:ParallelGCThreads=n |
并行垃圾收集使用的线程数,默认与处理器核心数相等,如果CPU很多,可以减小此值 |
-XX:+UseAdaptiveSizePolicy |
设置此选项后,并行收集器(Parallel Scavenge)会自动选择年轻代区大小和相应的Survivor区比例,以达到目标系统规定的最低响应时间或者收集频率等,建议使用并行收集器时启用。使用-XX:+PrintAdaptiveSizePolicy跟踪动态变化 |
-XX:+UseConcMarkSweepGC |
低停顿收集器。对年老代使用CMS垃圾回收器,同时保证应用的运行只有很短暂的停顿(1.4.1+) |
-XX:+CMSConcurrentMTEnabled |
CMS并发阶段(concurrent CMS phases)是否使用多线程(使用ParNewGC的情况下)。默认已经启用,设置-XX:-CMSConcurrentMTEnabled可以禁用 |
-XX:+CMSParallelRemarkEnabled |
在CMS重标记阶段,使用多线程来降低停顿时间。默认false。不一定能达到效果,需要进行基准测试(benchmark)来确定是否开启 |
-XX:CMSScheduleRemarkEdenSizeThreshold |
在预清理后,启动可中断预清理阶段的Eden占用最小值,默认2MB |
-XX:CMSScheduleRemarkEdenPenetration |
当新生代存活对象占Eden的比例超过多少时,终止preclean阶段并进入remark阶段,默认50 |
-XX:CMSMaxAbortablePrecleanTime |
设置CMS可中断预清理(preclean)阶段最大时间,单位毫秒,超过了强制进入重标记阶段 |
-XX:+CMSScavengeBeforeRemark |
在CMS的重标记阶段开始前,进行YGC清理,减少重标记阶段的耗时 |
-XX:ConcGCThreads=n | CMS垃圾收集(所有阶段)使用的线程数,提高此值可能改善垃圾回收性能,但是带来额外的同步成本(synchronization overhead)。默认的,此值不会明确设置,JVM根据-XX:ParallelGCThread来自动设置,公式为:ConcGCThreads = (ParallelGCThreads + 3)/4 |
-XX:+UseCMSInitiatingOccupancyOnly | 禁止HostSpot自行触发CMS GC,只有在堆百分比达到阈值时才触发,配合下一条使用 |
-XX:CMSInitiatingOccupancyFraction | 设置还剩余多少堆(百分比)时进行CMS收集,默认68%。如果年老代增长缓慢,可以增加此值。 |
-XX:CMSInitiatingPermOccupancyFraction |
设置还剩余多少永久带(百分比)时进行CMS收集 |
-XX:CMSFullGCsBeforeCompaction=5 |
由于CMS不对内存空间进行整理,此值设置运行多少次Full GC以后对内存空间进行整理。设置此参数可能导致promotion failure |
-XX:+UseCMSCompactAtFullCollection |
Full GC后对年老代进行整理。可能会影响性能,但是可以消除碎片。默认true |
-XX:+CMSIncrementalMode |
CMS增量模式,适用于单CPU情况 |
-XX:+CMSClassUnloadingEnabled |
启用CMS类卸载功能 |
-XX:+ScavengeBeforeFullGC |
Full GC前清理年轻代( 1.4.1+) |
-XX:+|-UseLargePages |
启用大内存分页支持 |
-XXLargePageSizeInBytes=n |
设置大内存分页的最大尺寸 |
-XX:MaxHeapFreeRatio=70 |
GC后,堆的最大空余百分比 |
-XX:MinHeapFreeRatio=40 |
GC后,堆的最小空余百分比 |
-XX:ReservedCodeCacheSize=32m |
最大代码缓存大小 |
-XX:CompileThreshold=10000 |
进行编译前,方法被执行的次数[-client: 1,500] |
-XX:ThreadStackSize=512 |
线程堆栈大小 |
-XX:+UseFastAccessorMethods |
使用优化版的Get方法 |
-XX:+UseLargePages |
使用大页(large page)内存 |
-XX:+UseMPSS |
使用多内存页大小支持 |
-XX:+UseStringCache |
缓存普通分配的字符串 |
-XX:+UseCompressedStrings |
压缩字符串 (6u21+) |
-XX:+OptimizeStringConcat |
优化字符串连接(6u21+) |
-XX:MaxDirectMemorySize |
NIO中通过Direct内存来提高性能,这个区域的大小默认是64M,在适当的场景可以设置大一些 |
-Xrs |
减少JVM对系统信号(Signals)使用 |
-XX:+AggressiveOpts |
启用在未来版本可能作为默认开启的优化选项(5.0u6) |
-XX:SoftRefLRUPolicyMSPerMB=0 |
启用积极的软引用处理,如果软引用对垃圾回收有影响了,可以使用。默认值为每兆1000毫秒。即对于堆中每MB大小的可用空间而言,一个软引用有1秒的存活时间(在最后一个强引用的对象被回收后) |
-XX:+DisableExplicitGC |
禁止System.gc()的调用 |
-XX:+UseGCOverheadLimit |
抛出OutOfMemory前,允许的GC占用虚拟机时间的最大比例(6.0+) |
参数 | 说明 |
-XX:+UseG1GC | 开启G1垃圾回收器 |
-XX:InitiatingHeapOccupancyPercent=n | 堆占用了多少时触发GC,默认为45 |
-XX:MaxTenuringThreshold | 默认15 |
-XX:MaxGCPauseMillis=n | |
-XX:NewRatio=n | 默认2 |
-XX:SurvivorRatio=n | 默认8 |
-XX:ParallelGCThreads=n | 并行GC的线程数 |
-XX:ConcGCThreads=n | 并发GC使用的线程数 |
-XX:G1ReservePercent=n | 设置作为空闲空间的预留内存百分比,以降低目标空间溢出的风险。默认值是 10% |
-XX:G1HeapRegionSize=n | 设置G1区域的大小。值是2的幂,范围是1 MB 到32 MB |
参数与默认值 |
说明 |
||
-XX:-CITime |
打印JIT编译器消耗的时间(1.4.0+) |
||
-XX:ErrorFile=./hs_err_pid%p.log |
如果JVM错误发生,将错误保存到指定位置(6.0+) 例如 -XX:ErrorFile=F:\Temp\hs_err_pid%p.log(注意,在Windows的BAT脚本中%要换为%%) |
||
-XX:+HeapDumpOnOutOfMemoryError |
java.lang.OutOfMemoryError发生时,是否Dump堆镜像(1.4.2u12+, 5u7+) |
||
-XX:+HeapDumpBeforeFullGC |
在FGC前Dump出堆内存 |
||
-XX:+HeapDumpAfterFullGC | 在FGC后Dump出堆内存 | ||
-XX:HeapDumpPath=/dir/ |
堆Dump文件的存储位置(1.4.2u12+, 5u7+) 例如 -XX:HeapDumpPath=F:\Temp\ |
||
-XX:OnError="CMD" |
出现致命错误时,运行用户定义的命令(1.4.2u9+) |
||
-XX:OnOutOfMemoryError="CMD" |
出现内存溢出时,运行用户定义的命令(1.4.2u12+,6.0) |
||
-XX:-PrintCommandLineFlags |
打印附加的命令行标记 (5.0+) |
||
-XX:-PrintCompilation |
当方法被编译时,打印信息 | ||
-XX:+PrintTLAB |
打印TLAB分配的情况 | ||
-XX:-PrintGC |
当GC活动时,打印信息 |
||
-XX:-PrintGCDetails |
打印GC详细信息 (1.4.0+) |
||
-XX:+PrintGCDateStamps |
打印GC时间,形式:2014-11-17T16:05:24.673+0800 |
||
-XX:-PrintGCTimeStamps |
打印GC时间戳(相对时间),形式:0.104 |
||
-XX:-TraceClassLoading |
跟踪类加载 | ||
-XX:-TraceClassResolution |
跟踪常量池解析 (1.4.2+) |
||
-XX:-TraceClassUnloading |
跟踪类的卸载 | ||
-XX:+PerfDataSaveToFile |
退出时保存二进制的JVM统计信息到文件 | ||
-XX:+UseCompressedOops |
使用压缩指针 |
||
-XX:InlineSmallCode=n |
内联之前编译好的方法,如果其大小小于n |
||
-XX:MaxInlineSize=35 |
内联方法最大字节码大小 |
||
-XX:FreqInlineSize=n |
频繁使用的方法内联的最大字节码大小 |
||
-Xloggc |
记录GC冗长信息到文件(不指定则记录到stdout)
|
||
-XX:-UseGCLogFileRotation |
记录GC冗长信息到文件时,启用文件轮换 | ||
-XX:NumberOfGClogFiles=1 |
上述文件轮换时,文件的个数 | ||
-XX:GCLogFileSize=8K |
GC冗长日志的大小 |
||
-XX:+PrintGCApplicationConcurrentTime |
打印GC程序并发时间 |
||
-XX:+PrintGCApplicationStoppedTime |
打印GC停顿时间 |
||
-XX:+PrintTenuringDistribution |
显示在Survivor区域里面有效的对象的年龄,ParNewGC分析此区域老对象的关系较为耗时 |
||
-XX:PrintFLSStatistics=N |
打印FreeListSpace的统计信息,可以得到内存碎片的信息 |
||
-Xprof |
剖析系统性能并输出到stdout |
- 响应时间优先:尽量大,直到接近最低响应时间的需求限制
- 吞吐量优先:尽量大,最好到达Gbits
- 响应时间优先:年老代默认CMS收集,需要考虑会话并发数、持续时间等因素,太小,造成碎片、高频回收、暂停并导致标记清除;太大,导致收集时间长。根据:CMS收集信息、次数、年轻代/年老代回收时间比率确定
- 吞吐量优先:一般都是较大的年轻代、较小的年老代。由于并发大,年轻代对象多,所以要求尽快收集年轻代对象,年老代存放长期存活对象
- 小堆引起的内存碎片问题:CMS算法不会对堆进行整理,导致碎片问题,配置 -XX:+UseCMSCompactAtFullCollection、-XX:CMSFullGCsBeforeCompaction来启用整理
7u9以后的版本,可以使用G1回收器,这是一个新型、综合的垃圾回收器。
可以使用类似如下方式启用:java -Xmx2G -Xms2G -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:G1ReservePercent=20 -XX:ConcGCThreads=8
一般认为64bit虚拟机的性能低于32位,所有某些时候32bit虚拟机集群比一个大的64bit虚拟机更合适。
如果JVM内存配置很大,DUMP内存映像将是非常耗时的,这和磁盘写入速度有关系
对于年轻代来说,非常大的内存空间不会对性能造成显著影响;而对于年老代,除非使用CMS垃圾回收器(默认是吞吐量优先的Parallel Old),否则可能导致很长的GC停顿(30G以内的内存可能数十秒 ,更高的内存可能数分钟),这对于用户交互式程序是无法忍受的。
CMS对于大概小于4G的堆来说,其初始标记、重标记STW时间较短,对于频繁制造垃圾的大堆,则亦可能出现问题,当CMS的工作跟不上年老代被占满的步伐时,会导致STW的串行垃圾回收器被启用,在16G内存下,这可能导致30秒或者更多的停顿,尽早(年老代被占用百分比)启用CMS,可能在一定程度上减少STW出现几率。注意,越是多核心的处理器,越可能导致CMS停顿的问题,因为CMS只会使用一个核心。
G1垃圾回收器不能解决CMS的问题,它的吞吐量甚至低于CMS。
- 对于G1垃圾回收器:避免使用 -Xmn 选项或 -XX:NewRatio 等其他相关选项显式设置年轻代大小,因为固定年轻代的大小会覆盖暂停时间目标
- 让堆的最小、最大尺寸一致
- 为新生代提供足够的空间,使大部分对象停留在新生代,同时,要避免老年代触发垃圾收集(保持有10-20%的空闲空间)
- 让新生代对象生命周期尽量短,避免使其进入年老代
- 避免短命的大对象,-XX:PretenureSizeThreshold设置直接进入年老代的阈值
- 将需要大量内存的模块使用C++等手工管理内存的语言实现
- 如果有海量内存,可以使用具有低延迟、无停顿GC的虚拟机,例如Azul,它的C4回收器具有这样的特征
CMS相关垃圾回收的可能原因有:
- System.gc() 的调用
- 老年代占比超过-XX:CMSInitiatingOccupancyFraction
- 如果启用-XX:+CMSClassUnloadingEnabled,当永久代占比超过-XX:CMSInitiatingPermOccupancyFraction
- 晋升失败(Promotion Failed):YGC时,Survivor区放不下所有对象,而且老年代也放不下,原因不一定是老年代空间不足,也可能是老年代碎片引起
- 并发模式失败(Concurrent Mode Failure ):CMS的同时进行YGC,导致CMS完成前老年代空间不足(Full Promotion Guarantee Failure),此情况下会发生Full GC。可能需要调小新生代或者减小-XX:CMSInitiatingOccupancyFraction
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
'前缀时间戳,例如221810.102,表示JVM已经启动的秒数' '时间times:user表示对于当前进程CPU消耗在user-mode的时间;sys表示对于当前进程CPU消耗在kernel-mode的时间;real表示物理时间的时间;' 'ParNew的年轻代垃圾收集(YGC),20024K为GC开始时的内存占用,497K为GC结束后的内存占用,39296K为总大小,0.0046067 为新生代局部收集消耗时间' '后面的20024K->9715K(126720K)表示整个堆收集前后内存占用和总内存,最后的Times显示GC过程中的总时间消耗' 0.102: [GC0.102: [ParNew: 20024K->497K(39296K), 0.0046067 secs] 20024K->9715K(126720K), 0.0046827 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 0.172: [GC0.172: [ParNew: 19990K->599K(39296K), 0.0009549 secs] '初始标记:STW,单线程(可以从user和real几乎相等看出),只标记ROOT能直接可达的对象,一般应该很快' '786428K表示年老代已占用空间;后面的786432K表示年老代总空间' 221810.417: [GC [1 CMS-initial-mark: 786428K(786432K)] 4527562K(5740992K), 3.1298768 secs] [Times: user=3.14 sys=0.00, real=3.16 secs] 221813.547: [CMS-concurrent-mark-start] '并发标记阶段,不会STW' 221814.218: [CMS-concurrent-mark: 0.670/0.671 secs] [Times: user=2.46 sys=0.00, real=0.64 secs] '预清理,不会STW。该阶段检查并发标记阶段时从新生代晋升的对象、新分配的对象、被应用程序线程更新过的对象,减少重新标记阶段的暂停时间' 221814.218: [CMS-concurrent-preclean-start] 221814.223: [CMS-concurrent-preclean: 0.005/0.005 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] '如果Eden占用量大于CMSScheduleRemarkEdenSizeThreshold(默认2M),会启动可中断预清理(不会STW)' 221814.223: [CMS-concurrent-abortable-preclean-start] 221814.223: [CMS-concurrent-abortable-preclean: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] '预清理阶段只是一个取样过程,它将新生代按一定间隔进行分块,标记起始位置,以便remark时可以并行的的对块进行Trace' '预清理阶段最好发生一次YGC,-XX:CMSScavengeBeforeRemark可以强制重标记前发生YGC' 221814.224: [GC[YG occupancy: 3774483 K (4954560 K)] 221814.224: [Rescan (parallel) , 4.1513281 secs] 221818.375: [weak refs processing, 0.0000280 secs] 221818.375: [scrub string table, 0.0014394 secs] '重新标记,STW,多线程,默认通过-XX:ParallelGCThreads计算得到线程数,此阶段通常是CMS中暂停时间最长的' [1 CMS-remark: 786428K(786432K)] 4560911K(5740992K), 4.1529812 secs] [Times: user=28.08 sys=0.00, real=4.17 secs] '并发清理,不会STW' 221818.377: [CMS-concurrent-sweep-start] CMS: Large Block: 0x00000007f8000000; Proximity: 0x00000007f7851ea0 -> 0x00000007f7851ea0 CMS: Large block 0x0000000000000000 221818.736: [CMS-concurrent-sweep: 0.358/0.358 secs] [Times: user=0.87 sys=0.00, real=0.36 secs] '重置,CMS数据结构重新初始化,为下一次CMS做准备' 221818.736: [CMS-concurrent-reset-start] 221818.738: [CMS-concurrent-reset: 0.002/0.002 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] '紧跟着一次并发模式失败的Full GC' 221890.743: [GC221890.743: [ParNew: 18434K->18434K(39296K), 0.0000233 secs]90.743: [CMS90.743: [CMS-concurrent-abortable-preclean: 0.000/0.028 secs] [Times: user=0.02 sys=0.00, real=0.03 secs] (concurrent mode failure): 83535K->37453K(87424K), 0.0111540 secs] 101969K->37453K(126720K), [CMS Perm : 3284K->3284K(65536K)], 0.0112398 secs] [Times: user=0.02 sys=0.00, real=0.01 secs] 221890.754: [Full GC221890.754: [CMS: 37453K->37453K(87424K), 0.0051618 secs] 37453K->37453K(126720K), [CMS Perm : 3284K->3284K(65536K)], 0.0051982 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] |
开启:-XX:+PrintTenuringDistribution可以打印分布信息
1 2 3 4 5 |
'期望的Survivor区占用由-XX:TargetSurvivorRatio=50指定' 'threshold 即晋升的年龄限制,可由-XX:MaxTenuringThreshold指定' Desired survivor size 2228224 bytes, new threshold 6 (max 6) - age 1: 232 bytes, 232 total - age 2: 478840 bytes, 479072 total '各年龄对象的字节数、数量' |
开启-XX:+PrintGCApplicationConcurrentTime、-XX:+PrintGCApplicationStoppedTime可以打印并发时间、停顿时间
1 2 3 4 |
'应用和GC并发执行的时间' Application time: 0.0362382 seconds '应用被GC停止的时间' Total time for which application threads were stopped: 0.0039536 seconds |
开启 -XX:+PrintFlagsFinal可以打印所有GC标记
1 2 3 4 5 |
[Global flags] uintx AdaptivePermSizeWeight = 20 {product} uintx AdaptiveSizeDecrementScaleFactor = 4 {product} uintx AdaptiveSizeMajorGCDecayTimeScale = 10 {product} …… |
开启-XX:PrintFLSStatistics=1可以统计内存碎片
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
Before GC: Statistics for BinaryTreeDictionary: ------------------------------------ Total Free Space: 11190272 Max Chunk Size: 11190272 Number of Blocks: 1 Av. Block Size: 11190272 Tree Height: 1 After GC: Statistics for BinaryTreeDictionary: ------------------------------------ Total Free Space: 9993976 Max Chunk Size: 9993976 Number of Blocks: 1 Av. Block Size: 9993976 Tree Height: 1 |
Leave a Reply