jvm调优(二)

简介: jvm调优

2.5.jstat(JVM统计监测工具)


语法格式如下:


jstat [ generalOption | outputOptions vmid [interval[s|ms] [count]] ]


vmid是Java虚拟机ID,在Linux/Unix系统上一般就是进程ID。interval是采样时间间隔。count是采样数目。比如下面输出的是GC信息,采样时间间隔为250ms,采样数为4:


root@ubuntu:/# jstat -gc 21711 250 4
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       PC     PU    YGC     YGCT    FGC    FGCT     GCT  
192.0  192.0   64.0   0.0    6144.0   1854.9   32000.0     4111.6   55296.0 25472.7    702    0.431   3      0.218    0.649
192.0  192.0   64.0   0.0    6144.0   1972.2   32000.0     4111.6   55296.0 25472.7    702    0.431   3      0.218    0.649
192.0  192.0   64.0   0.0    6144.0   1972.2   32000.0     4111.6   55296.0 25472.7    702    0.431   3      0.218    0.649
192.0  192.0   64.0   0.0    6144.0   2109.7   32000.0     4111.6   55296.0 25472.7    702    0.431   3      0.218    0.649

要明白上面各列的意义,先看JVM堆内存布局:


1fba15b8839f4c4687777ce387694b2e.png


可以看出:


堆内存 = 年轻代 + 年老代 + 永久代

年轻代 = Eden区 + 两个Survivor区(From和To)


现在来解释各列含义:


S0C、S1C、S0U、S1U:Survivor 0/1区容量(Capacity)和使用量(Used)

EC、EU:Eden区容量和使用量

OC、OU:年老代容量和使用量

PC、PU:永久代容量和使用量

YGC、YGT:年轻代GC次数和GC耗时

FGC、FGCT:Full GC次数和Full GC耗时

GCT:GC总耗时


2.6.hprof(Heap/CPU Profiling Tool)


hprof能够展现CPU使用率,统计堆内存使用情况。


语法格式如下:


java -agentlib:hprof[=options] ToBeProfiledClass


java -Xrunprof[:options] ToBeProfiledClass


javac -J-agentlib:hprof[=options] ToBeProfiledClass

完整的命令选项如下:

Option Name and Value  Description                    Default
---------------------  -----------                    -------
heap=dump|sites|all    heap profiling                 all
cpu=samples|times|old  CPU usage                      off
monitor=y|n            monitor contention             n
format=a|b             text(txt) or binary output     a
file=<file>            write data to file             java.hprof[.txt]
net=<host>:<port>      send data over a socket        off
depth=<size>           stack trace depth              4
interval=<ms>          sample interval in ms          10
cutoff=<value>         output cutoff point            0.0001
lineno=y|n             line number in traces?         y
thread=y|n             thread in traces?              n
doe=y|n                dump on exit?                  y
msa=y|n                Solaris micro state accounting n
force=y|n              force output to <file>         y
verbose=y|n            print messages about dumps     y

来几个官方指南上的实例。


CPU Usage Sampling Profiling(cpu=samples)的例子:


java -agentlib:hprof=cpu=samples,interval=20,depth=3 Hello


上面每隔20毫秒采样CPU消耗信息,堆栈深度为3,生成的profile文件名称是java.hprof.txt,在当前目录。


CPU Usage Times Profiling(cpu=times)的例子,它相对于CPU Usage Sampling Profile能够获得更加细粒度的CPU消耗信息,能够细到每个方法调用的开始和结束,它的实现使用了字节码注入技术(BCI):


javac -J-agentlib:hprof=cpu=times Hello.java


Heap Allocation Profiling(heap=sites)的例子:


javac -J-agentlib:hprof=heap=sites Hello.java


Heap Dump(heap=dump)的例子,它比上面的Heap Allocation Profiling能生成更详细的Heap Dump信息:


javac -J-agentlib:hprof=heap=dump Hello.java


虽然在JVM启动参数中加入-Xrunprof:heap=sites参数可以生成CPU/Heap Profile文件,但对JVM性能影响非常大,不建议在线上服务器环境使用。


2.7.jconsole、jvisualvm


利用jconsole、jvisualvm分析内存信息(各个区如Eden、Survivor、Old等内存变化情况),如果查看的是远程服务器的JVM,程序启动需要加上如下参数:


"-Dcom.sun.management.jmxremote=true" 
"-Djava.rmi.server.hostname=12.34.56.78" 
"-Dcom.sun.management.jmxremote.port=18181" 
"-Dcom.sun.management.jmxremote.authenticate=false" 
"-Dcom.sun.management.jmxremote.ssl=false"

下图是jconsole界面,概览选项可以观测堆内存使用量、线程数、类加载数和CPU占用率;内存选项可以查看堆中各个区域的内存使用量和左下角的详细描述(内存大小、GC情况等);线程选项可以查看当前JVM加载的线程,查看每个线程的堆栈信息,还可以检测死锁;VM概要描述了虚拟机的各种详细参数。(jconsole功能演示)


b0732336808e40c78c2fb6e5cc1ca834.png


下图是jvisualvm的界面,功能比jconsole略丰富一些,不过大部分功能都需要安装插件。概述跟jconsole的VM概要差不多,描述的是jvm的详细参数和程序启动参数;监视展示的和jconsole的概览界面差不多(CPU、堆/方法区、类加载、线程);线程和jconsole的线程界面差不多;抽样器可以展示当前占用内存的类的排行榜及其实例的个数;Visual GC可以更丰富地展示当前各个区域的内存占用大小及历史信息(下图)(jvisualvm功能演示)


工具路径://java/jdk1.8xxx/bin/JVisuaVM.exe


监控本地的Tomcat

监控远程Tomcat

监控普通的JAVA进程


eea85b5fa1634f7fb48c9ccf8859f878.png


这个有不懂得可以看此文:如何利用 JConsole观察分析Java程序的运行,进行排错调优


2.8.jinfo


jinfo命令主要用于查看应用程序的配置参数,以及打印运行JVM时候所指定的JVM参数。jinfo可以使用-sysprops选项将虚拟机进程中所指定的System.getProperties()的内容打印出来,并且该命令还可以查看未被显示指定的JVM参数的系统默认值,这通过jps -v是无法看到的。同时jinfo命令还能够在运行期修改JVM参数,通过使用 -flag name=value 或者 -flag [+|-]name 来修改一部分运行期可修改的虚拟机参数


其他的一些工具如BTrace、Reference等有兴趣可以自己查下资料的


2.9.依赖、参考的数据有系统运行日志、堆栈错误信息、gc日志、线程快照、堆转储快照进行调优


此处参考大佬的文章:JVM性能调优 倒也不失为一种思路 大家可根据自己业务场景或者其他因素进行筛选使用


①系统运行日志:系统运行日志就是在程序代码中打印出的日志,描述了代码级别的系统运行轨迹(执行的方法、入参、返回值等),一般系统出现问题,系统运行日志是首先要查看的日志。


②堆栈错误信息:当系统出现异常后,可以根据堆栈信息初步定位问题所在,比如根据“java.lang.OutOfMemoryError: Java heap space”可以判断是堆内存溢出;根据“java.lang.StackOverflowError”可以判断是栈溢出;根据“java.lang.OutOfMemoryError: PermGen space”可以判断是方法区溢出等。


③GC日志:程序启动时用 -XX:+PrintGCDetails 和 -Xloggc:/data/jvm/gc.log 可以在程序运行时把gc的详细过程记录下来,或者直接配置“-verbose:gc”参数把gc日志打印到控制台,通过记录的gc日志可以分析每块内存区域gc的频率、时间等,从而发现问题,进行有针对性的优化。


比如如下一段GC日志:


2018-08-02T14:39:11.560-0800: 10.171: [GC [PSYoungGen: 30128K->4091K(30208K)] 51092K->50790K(98816K), 0.0140970 secs] [Times: user=0.02 sys=0.03, real=0.01 secs] 
2018-08-02T14:39:11.574-0800: 10.185: [Full GC [PSYoungGen: 4091K->0K(30208K)] [ParOldGen: 46698K->50669K(68608K)] 50790K->50669K(98816K) [PSPermGen: 2635K->2634K(21504K)], 0.0160030 secs] [Times: user=0.03 sys=0.00, real=0.02 secs] 
2018-08-02T14:39:14.045-0800: 12.656: [GC [PSYoungGen: 14097K->4064K(30208K)] 64766K->64536K(98816K), 0.0117690 secs] [Times: user=0.02 sys=0.01, real=0.01 secs] 
2018-08-02T14:39:14.057-0800: 12.668: [Full GC [PSYoungGen: 4064K->0K(30208K)] [ParOldGen: 60471K->401K(68608K)] 64536K->401K(98816K) [PSPermGen: 2634K->2634K(21504K)], 0.0102020 secs] [Times: user=0.01 sys=0.00, real=0.01 secs]

上面一共是4条GC日志,来看第一行日志,“2018-08-02T14:39:11.560-0800”是精确到了毫秒级别的UTC 通用标准时间格式,配置了“-XX:+PrintGCDateStamps”这个参数可以跟随gc日志打印出这种时间戳,“10.171”是从JVM启动到发生gc经过的秒数。第一行日志正文开头的“[GC”说明这次GC没有发生Stop-The-World(用户线程停顿),第二行日志正文开头的“[Full GC”说明这次GC发生了Stop-The-World,所以说,[GC和[Full GC跟新生代和老年代没关系,和垃圾收集器的类型有关系,如果直接调用System.gc(),将显示[Full GC(System)。接下来的“[PSYoungGen”、“[ParOldGen”表示GC发生的区域,具体显示什么名字也跟垃圾收集器有关,比如这里的“[PSYoungGen”表示Parallel Scavenge收集器,“[ParOldGen”表示Serial Old收集器,此外,Serial收集器显示“[DefNew”,ParNew收集器显示“[ParNew”等。再往后的“30128K->4091K(30208K)”表示进行了这次gc后,该区域的内存使用空间由30128K减小到4091K,总内存大小为30208K。每个区域gc描述后面的“51092K->50790K(98816K), 0.0140970 secs”进行了这次垃圾收集后,整个堆内存的内存使用空间由51092K减小到50790K,整个堆内存总空间为98816K,gc耗时0.0140970秒。


④线程快照:顾名思义,根据线程快照可以看到线程在某一时刻的状态,当系统中可能存在请求超时、死循环、死锁等情况是,可以根据线程快照来进一步确定问题。通过执行虚拟机自带的“jstack pid”命令,可以dump出当前进程中线程的快照信息,更详细的使用和分析网上有很多例,这篇文章写到这里已经很长了就不过多叙述了,贴一篇博客供参考:http://www.cnblogs.com/kongzhongqijing/articles/3630264.html


⑤堆转储快照:程序启动时可以使用 “-XX:+HeapDumpOnOutOfMemory” 和 “-XX:HeapDumpPath=/data/jvm/dumpfile.hprof”,当程序发生内存溢出时,把当时的内存快照以文件形式进行转储(也可以直接用jmap命令转储程序运行时任意时刻的内存快照),事后对当时的内存使用情况进行分析。


三、jvm调优经验总结


3.1.调优的最终目标是什么



1.GC的时间足够的小

2.GC的次数足够的少

3.发生Full GC的周期足够的长


前两个目前是相悖的,要想GC时间小必须要一个更小的堆,要保证GC次数足够少,必须保证一个更大的堆,我们只能取其平衡。


更大的年轻代必然导致更小的年老代,大的年轻代会延长普通GC的周期,但会增加每次GC的时间;小的年老代会导致更频繁的Full GC


更小的年轻代必然导致更大年老代,小的年轻代会导致普通GC很频繁,但每次的GC时间会更短;大的年老代会减少Full GC的频率


如何选择应该依赖应用程序对象生命周期的分布情况:如果应用存在大量的临时对象,应该选择更大的年轻代;如果存在相对较多的持久对象,年老代应该适当增大。


但很多应用都没有这样明显的特性,在抉择时应该根据以下两点:a、本着Full GC尽量少的原则,让年老代尽量缓存常用对象,JVM的默认比例3:8也是这个道理


(B)通过观察应用一段时间,看其他在峰值时年老代会占多少内存,在不影响FullGC的前提下,根据实际情况加大年轻代,比如可以把比例控制在1:1。但应该给年老代至少预留1/3的增长空间


3.2.将新对象预留在年轻代


众所周知,由于 Full GC 的成本远远高于 Minor GC,因此某些情况下需要尽可能将对象分配在年轻代,这在很多情况下是一个明智的选择。虽然在大部分情况下,JVM 会尝试在 Eden 区分配对象,但是由于空间紧张等问题,很可能不得不将部分年轻对象提前向年老代压缩。因此,在 JVM 参数调优时可以为应用程序分配一个合理的年轻代空间,以最大限度避免新对象直接进入年老代的情况发生。


通过设置一个较大的年轻代预留新对象,设置合理的 Survivor 区并且提供 Survivor 区的使用率,可以将年轻对象保存在年轻代。一般来说,Survivor 区的空间不够,或者占用量达到 50%时,就会使对象进入年老代(不管它的年龄有多大)


我们可以尝试加上


-XX:TargetSurvivorRatio=90


参数,这样可以提高 from 区的利用率,使 from 区使用到 90%时,再将对象送入年老代


3.3.让大对象进入年老代


我们在大部分情况下都会选择将对象分配在年轻代。但是,对于占用内存较多的大对象而言,它的选择可能就不是这样的。因为大对象出现在年轻代很可能扰乱年轻代 GC,并破坏年轻代原有的对象结构。因为尝试在年轻代分配大对象,很可能导致空间不足,为了有足够的空间容纳大对象,JVM 不得不将年轻代中的年轻对象挪到年老代。因为大对象占用空间多,所以可能需要移动大量小的年轻对象进入年老代,这对 GC 相当不利。


基于以上原因,可以将大对象直接分配到年老代,保持年轻代对象结构的完整性,这样可以提高 GC 的效率。如果一个大对象同时又是一个短命的对象,假设这种情况出现很频繁,那对于 GC 来说会是一场灾难。原本应该用于存放永久对象的年老代,被短命的对象塞满,这也意味着对堆空间进行了洗牌,扰乱了分代内存回收的基本思路。因此,在软件开发过程中,应该尽可能避免使用短命的大对象。


可以使用参数


-XX:PetenureSizeThreshold


设置大对象直接进入年老代的阈值。当对象的大小超过这个值时,将直接在年老代分配。参数-XX:PetenureSizeThreshold 只对串行收集器和年轻代并行收集器有效,并行回收收集器不识别这个参数。


3.4. 设置对象进入年老代的年龄


如何设置对象进入年老代的年龄


堆中的每一个对象都有自己的年龄。一般情况下,年轻对象存放在年轻代,年老对象存放在年老代。为了做到这点,虚拟机为每个对象都维护一个年龄。如果对象在 Eden 区,经过一次 GC 后依然存活,则被移动到 Survivor 区中,对象年龄加 1。以后,如果对象每经过一次 GC 依然存活,则年龄再加 1。当对象年龄达到阈值时,就移入年老代,成为老年对象。


这个阈值的最大值可以通过参数


-XX:MaxTenuringThreshold

来设置,默认值是 15。虽然-XX:MaxTenuringThreshold 的值可能是 15 或者更大,但这不意味着新对象非要达到这个年龄才能进入年老代。事实上,对象实际进入年老代的年龄是虚拟机在运行时根据内存使用情况动态计算的,这个参数指定的是阈值年龄的最大值。即,实际晋升年老代年龄等于动态计算所得的年龄与-XX:MaxTenuringThreshold 中较小的那个。


3.5.稳定的 Java 堆 VS 动荡的 Java 堆


一般来说,稳定的堆大小对垃圾回收是有利的。获得一个稳定的堆大小的方法是使-Xms 和-Xmx 的大小一致,即最大堆和最小堆 (初始堆)一样


如果这样设置,系统在运行时堆大小理论上是恒定的,稳定的堆空间可以减少 GC 的次数。因此,很多服务端应用都会将最大堆和最小堆设置为相同的数值。但是,一个不稳定的堆并非毫无用处。稳定的堆大小虽然可以减少 GC 次数,但同时也增加了每次GC的时间。让堆大小在一个区间中震荡,在系统不需要使用大内存时,压缩堆空间,使 GC 应对一个较小的堆,可以加快单次 GC 的速度。基于这样的考虑,JVM 还提供了两个参数用于压缩和扩展堆空间。


-XX:MinHeapFreeRatio


参数用来设置堆空间最小空闲比例,默认值是 40。当堆空间的空闲内存小于这个数值时,JVM 便会扩展堆空间。


-XX:MaxHeapFreeRatio

参数用来设置堆空间最大空闲比例,默认值是 70。当堆空间的空闲内存大于这个数值时,便会压缩堆空间,得到一个较小的堆。


当**-Xmx 和-Xms 相等时,-XX:MinHeapFreeRatio 和-XX:MaxHeapFreeRatio 两个参数无效**。


3.6.增大吞吐量提升系统性能


吞吐量优先的方案将会尽可能减少系统执行垃圾回收的总时间,故可以考虑关注系统吞吐量的并行回收收集器。在拥有高性能的计算机上,进行吞吐量优先优化,可以使用参数:


java –Xmx3800m –Xms3800m –Xmn2G –Xss128k –XX:+UseParallelGC 
   –XX:ParallelGC-Threads=20 –XX:+UseParallelOldGC

–Xmx380m –Xms3800m:设置 Java 堆的最大值和初始值。一般情况下,为了避免堆内存的频繁震荡,导致系统性能下降,我们的做法是设置最大堆等于最小堆。假设这里把最小堆减少为最大堆的一半,即 1900m,那么 JVM 会尽可能在 1900MB 堆空间中运行,如果这样,发生 GC 的可能性就会比较高;


-Xss128k:减少线程栈的大小,这样可以使剩余的系统内存支持更多的线程;


-Xmn2g:设置年轻代区域大小为 2GB;


–XX:+UseParallelGC:年轻代使用并行垃圾回收收集器。这是一个关注吞吐量的收集器,可以尽可能地减少 GC 时间。


–XX:ParallelGC-Threads:设置用于垃圾回收的线程数,通常情况下,可以设置和 CPU 数量相等。但在 CPU 数量比较多的情况下,设置相对较小的数值也是合理的;

–XX:+UseParallelOldGC:设置年老代使用并行回收收集器。


3.7.尝试使用大的内存分页


CPU 是通过寻址来访问内存的。32 位 CPU 的寻址宽度是 0~0xFFFFFFFF ,计算后得到的大小是 4G,也就是说可支持的物理内存最大是 4G。但在实践过程中,碰到了这样的问题,程序需要使用 4G 内存,而可用物理内存小于 4G,导致程序不得不降低内存占用。为了解决此类问题,现代 CPU 引入了 MMU(Memory Management Unit 内存管理单元)。MMU 的核心思想是利用虚拟地址替代物理地址,即 CPU 寻址时使用虚址,由 MMU 负责将虚址映射为物理地址。MMU 的引入,解决了对物理内存的限制,对程序来说,就像自己在使用 4G 内存一样。内存分页 (Paging) 是在使用 MMU 的基础上,提出的一种内存管理机制。它将虚拟地址和物理地址按固定大小(4K)分割成页 (page) 和页帧 (page frame),并保证页与页帧的大小相同。这种机制,从数据结构上,保证了访问内存的高效,并使 OS 能支持非连续性的内存分配。在程序内存不够用时,还可以将不常用的物理内存页转移到其他存储设备上,比如磁盘,这就是大家耳熟能详的虚拟内存。


在 Solaris 系统中,JVM 可以支持 Large Page Size 的使用。使用大的内存分页可以增强 CPU 的内存寻址能力,从而提升系统的性能。


java –Xmx2506m –Xms2506m –Xmn1536m –Xss128k –XX:++UseParallelGC
 –XX:ParallelGCThreads=20 –XX:+UseParallelOldGC –XX:+LargePageSizeInBytes=256m


–XX:+LargePageSizeInBytes:设置大页的大小。


过大的内存分页会导致 JVM 在计算 Heap 内部分区(perm, new, old)内存占用比例时,会出现超出正常值的划分,最坏情况下某个区会多占用一个页的大小。


3.8.使用非占有的垃圾回收器


为降低应用软件的垃圾回收时的停顿,首先考虑的是使用关注系统停顿的 CMS 回收器,其次,为了减少 Full GC 次数,应尽可能将对象预留在年轻代,因为年轻代 Minor GC 的成本远远小于年老代的 Full GC。


java –Xmx3550m –Xms3550m –Xmn2g –Xss128k –XX:ParallelGCThreads=20
 –XX:+UseConcMarkSweepGC –XX:+UseParNewGC –XX:+SurvivorRatio=8 –XX:TargetSurvivorRatio=90
 –XX:MaxTenuringThreshold=31

–XX:ParallelGCThreads=20:设置 20 个线程进行垃圾回收;


–XX:+UseParNewGC:年轻代使用并行回收器;


–XX:+UseConcMarkSweepGC:年老代使用 CMS 收集器降低停顿;


–XX:+SurvivorRatio:设置 Eden 区和 Survivor 区的比例为 8:1。稍大的 Survivor 空间

可以提高在年轻代回收生命周期较短的对象的可能性,如果 Survivor 不够大,一些短命的对象可能直接进入年老代,这对系统来说是不利的。


–XX:TargetSurvivorRatio=90:设置 Survivor 区的可使用率。这里设置为 90%,则允许 90%的 Survivor 空间被使用。默认值是 50%。故该设置提高了 Survivor 区的使用率。当存放的对象超过这个百分比,则对象会向年老代压缩。因此,这个选项更有助于将对象留在年轻代。


–XX:MaxTenuringThreshold:设置年轻对象晋升到年老代的年龄。默认值是 15 次,即对象经过 15 次 Minor GC 依然存活,则进入年老代。这里设置为 31,目的是让对象尽可能地保存在年轻代区域。


四、一些JVM参数


4.1.设定堆内存大小

-Xms:启动JVM时的堆内存空间。
-Xmx:堆内存最大限制。
-Xmn:设置年轻代大小整个堆大小=年轻代大小 + 年老代大小 + 持久代大小,Sun官方推荐配置为整个堆的3/8
-XX:PermSize=128M设置持久代大小
-XX:MaxPermSize=128M设置持久代最大值,此值可以设置与-XX:PermSize相同,防止持久代内存伸缩,持久代设置很重要,一般预留其使用空间的1/3.

4.2.设定新生代大小。

-XX:NewRatio:新生代和老年代的占比。
-XX:NewSize:新生代空间。
-XX:SurvivorRatio:伊甸园空间和幸存者空间的占比。
-XX:MaxTenuringThreshold:对象进入老年代的年龄阈值。

4.3.设定垃圾回收器

-XX:+UseSerialGC 开启串行收集器
-XX:+UseParallelGC开启年轻代并行收集器,JDK5.0以上,JVM会根据系统配置自行设置,所以无需再设置此值
-XX:+UseParallelOldGC开启老年代并行收集器
-XX:+UseConcMarkSweepGC开启老年代并发收集器(简称CMS),可以和UseParallelGC一起使用
-XX:CMSInitiatingOccupancyFraction=70老年代内存使用比例到多少激活CMS收集器,这个数值的设置有很大技巧基本上满足(Xmx-Xmn)*(100-CMSInitiatingOccupancyFraction)/100>=Xmn否则会出现“Concurrent Mode Failure”,promotionfailed,官方建议数值为68
-XX:+UseCMSCompactAtFullCollection:使用并发收集器时,开启对年老代的压缩

4.4.其他

-Xss: 设置每个线程的堆栈大小,设置每个线程的堆栈大小。JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。更具应用的线程所需内存大小进行调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右,这个参数对性能的影响比较大的
-XX:MaxTenuringThreshold=0:设置垃圾最大年龄。如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代。对于年老代比较多的应用,可以提高效率。如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收的概论,linux64的java6默认值是15
-XX:ParallelGCThreads=设置并行垃圾回收的线程数。此值可以设置与机器处理器数量相等(逻辑cpu数),这个不确定是物理、还是逻辑使用默认就好
-XX:MaxGCPauseMillis=指定垃圾回收时的最长暂停时间,单位毫秒,如果指定了此值的话,堆大小和垃圾回收相关参数会进行调整以达到指定值,设定此值可能会减少应用的吞吐量
-XX:GCTimeRatio=设定吞吐量为垃圾回收时间与非垃圾回收时间的比值,公式为1/(1+N)。例如,-XX:GCTimeRatio=19时,表示5%的时间用于垃圾回收。默认情况为99,即1%的时间用于垃圾回收
-XX:+UseAdaptiveSizePolicy:设置此选项后,并行收集器会自动选择年轻代区大小和相应的Survivor区比例,以达到目标系统规定的最低相应时间或者收集频率等,此值建议使用并行收集器时,一直打开
-XX:+DisableExplicitGC:禁止 java 程序中的 full gc, 如System.gc() 的调用. 最好加上, 防止程序在代码里误用了对性能造成冲击
-XX:+PrintGCDetails 打应垃圾收集的情况
-XX:+PrintGCTimeStamps 打应垃圾收集的情况
-XX:+PrintGCApplicationConcurrentTime:打印每次垃圾回收前,程序未中断的执行时间。可与上面混合使用
-XX:+PrintGCApplicationStoppedTime 打应垃圾收集时 , 系统的停顿时间
-XX:+PrintGC 打印GC情况
-XX:PrintHeapAtGC:打印GC前后的详细堆栈信息


目录
相关文章
|
3月前
|
算法 Java 关系型数据库
掌握这3个技巧,你也可以秒懂JAVA性能调优和jvm垃圾回收
JVM 是一个虚拟化的操作系统,类似于 Linux 和 Window,只是他被架构在了操作系统上进行接收 class 文件并把 class 翻译成系统识别的机器码进行执行,即 JVM 为我们屏蔽了不同操作系统在底层硬件和操作指令的不同。
25 0
|
4月前
|
监控 架构师 Java
JVM 11 调优指南:如何进行JVM调优,JVM调优参数
JVM 11的优化指南:如何进行JVM调优,以及JVM调优参数有哪些”这篇文章将包含JVM 11调优的核心概念、重要性、调优参数,并提供12个实用的代码示例,每个示例都会结合JVM调优参数和Java代码
118 2
|
4月前
|
存储 SQL 算法
jvm性能调优 - 11J线上VM调优案例分享
jvm性能调优 - 11J线上VM调优案例分享
61 0
|
4月前
|
存储 缓存 监控
JVM 21 的调优指南:如何进行JVM调优,JVM调优参数
聊聊关于JVM 21的优化指南。这篇文章将会深入探讨如何进行JVM调优,介绍一些关键的JVM调优参数,并提供12个实用的代码示例。由于篇幅较长,我会分几个部分来详细讲解,之前写的也有33篇系列教程JVM调优实战打击也可以去围观。
117 0
|
4月前
|
存储 监控 算法
垃圾回收器、垃圾回收算法、空间分配担保、JVM调优、GC回收对象的过程
垃圾回收器、垃圾回收算法、空间分配担保、JVM调优、GC回收对象的过程
|
4月前
|
监控 架构师 Java
JVM 8 调优指南:如何进行JVM调优,JVM调优参数
这篇文章将详细介绍如何进行JVM 8调优,包括JVM 8调优参数及其应用。此外,我将提供12个实用的代码示例,每个示例都会结合JVM启动参数和Java代码。JVM调优是指通过调整Java虚拟机的配置来提升Java应用程序的性能。这包括优化堆内存设置、选择合适的垃圾收集器以及调整其他性能相关的参数。
215 0
|
2月前
|
缓存 算法 安全
【JVM故障问题排查心得】「Java技术体系方向」Java虚拟机内存优化之虚拟机参数调优原理介绍(二)
【JVM故障问题排查心得】「Java技术体系方向」Java虚拟机内存优化之虚拟机参数调优原理介绍
18 0
|
2月前
|
缓存 Java C#
【JVM故障问题排查心得】「Java技术体系方向」Java虚拟机内存优化之虚拟机参数调优原理介绍(一)
【JVM故障问题排查心得】「Java技术体系方向」Java虚拟机内存优化之虚拟机参数调优原理介绍
86 0
|
4月前
|
监控 安全 架构师
JVM 17 调优指南:如何进行JVM调优,JVM调优参数
在这篇文章中,我会详细介绍JVM调优的概念、重要性和具体的JVM调优参数。此外,我将提供12个实用的代码示例,每个示例都会包含JVM调优参数和相应的Java代码。JVM调优是调整和配置Java虚拟机(JVM)的过程,以便最大限度地提高应用程序的性能和效率。这涉及到调整内存设置、选择合适的垃圾收集器,以及配置各种性能参数。
268 0
|
9天前
|
监控 Java
【JVM】深入理解JVM调优
【JVM】深入理解JVM调优
8 0