JVMのトラブルシューティングとチューニング

1.jps は
主に、JVM で実行されているプロセスのステータス情報を出力するために使用されます。
-q は、メイン メソッドに渡されるクラス名、Jar 名、およびパラメーター
を出力しません。 -m は、メイン メソッドに渡されるパラメーターを出力します。 -l は、
メイン クラスまたは Jar の完全名を出力します。 -v は、
JVM に渡されるパラメーターを出力します。

2. jstack
は主に Java プロセスのスレッド スタック情報を表示するために使用されます。形式は次のとおりです。
jstack [オプション] pid
jstack [オプション] 実行可能コア
jstack [オプション] [server-id@]remote-hostname-or-ip
-l 長いリスト、追加のロック情報を出力します。デッドロックが発生した場合、jstack -l pid を使用してロック保持ステータスを観察できます。 -m 混合モード。Java スタック情報を出力するだけでなく、C/C++ も出力します。スタック情報(Nativeメソッドなど
)

例1:找出java进程中最耗费CPU时间的线程,查看具体代码在哪里?
    (1) 查看进程的线程:top -Hp pid(也可用ps -Lfp pid或者ps -mp pid -o THREAD),根据时间排序,找到耗时最长的
    (2) printf "%x\n" 线程id -> 得到16进制值
    (3) jstack 线程id | grep 十六进制值,看到具体代码

3.jmap と jhat
jmap はヒープ メモリの使用状況を表示するために使用されます。形式は次のとおりです:
jmap [オプション] pid
jmap [オプション] 実行可能コア
jmap [オプション] [server-id@]remote-hostname-or-ip

jmap -heap pid:查看进程堆内存使用情况,包括使用的GC算法、堆配置参数和各代中堆内存使用情况
jmap -histo[:live] pid查看堆内存中的对象数目、大小统计直方图,如果带上live则只统计活对象

jmap -dump:format=b,file=dumpFileName pid :用jmap把进程内存使用情况dump到文件中,再用jhat分析查看, dump出来的文件可以用MAT、VisualVM等工具查看
jhat -port 9998 /tmp/dump.dat 注意如果Dump文件太大,可能需要加上-J-Xmx512m这种参数指定最大堆内存,即jhat -J-Xmx512m -port 8082 ./dump.dat。
然后就可以在浏览器中输入主机地址:8082查看了,*最下面有一个Other Queries, 可以看对象个数统计

4. jstat
JVM 統計監視ツールの形式は次のとおりです:
jstat [generalOption |outputOptions vmid [interval[s|ms] [count]] ]
vmid は Java 仮想マシン ID で、通常、Linux/Unix システムではプロセス ID です。間隔はサンプリング間隔です。count はサンプルの数です

如:jstat -gc 21711 250 4 采样时间间隔为250ms,采样数为4 
S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT   
6528.0 6528.0  0.0    0.0   52480.0  35761.7   65536.0    61680.2   68108.0 65068.0 8868.0 8235.8    293    6.354  715    37.002   43.356
6528.0 6528.0  0.0    0.0   52480.0  43995.4   65536.0    61680.2   68108.0 65068.0 8868.0 8235.8    293    6.354  716    37.038   43.392
6528.0 6528.0  0.0    0.0   52480.0  49876.9   65536.0    61680.2   68108.0 65068.0 8868.0 8235.8    293    6.354  716    37.038   43.392
6528.0 6528.0  0.0   6527.1 52480.0  52480.0   65536.0    61680.2   68108.0 65068.0 8868.0 8235.8    294    6.354  716    37.038   43.392

相关:
    堆内存 = 年轻代 + 年老代 + 永久代
    年轻代 = 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总耗时

5.hprof (ヒープ/CPU プロファイリング ツール)
hprof は CPU 使用率を表示し、ヒープ メモリ使用量をカウントできます 構文形式は次のとおりです: java -agentlib:
hprof[=options] ToBeProfiledClass
java -Xrunprof[:options] ToBeProfiledClass -Xrunprof:heap=sites パラメータを JVM 起動パラメータに追加すると、CPU/ヒープ プロファイル ファイルを生成できますが、JVM に大きな影響を与えます。パフォーマンスが高く、オンライン サーバー環境には推奨されません 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

6. jconsole と jvisualvm は
、メモリ情報 (Eden、Survivor、Old などのさまざまな領域のメモリ変更) を分析するために jdk に付属する 2 つの視覚化ツールです。リモート サーバーの JVM を表示している場合は、プログラムの開始時に次のパラメータを追加する必要があります: "-Dcom. jmxremote.port=18181" "-Dcom.sun.management.jmxremote.authenticate=false" "
-D
com.sun.management.jmxremote.ssl
=
false
"

7.
jinfo jinfo コマンドは主に、アプリケーションの構成パラメータを表示し、JVM の実行時に指定された JVM パラメータを出力するために使用されます。jinfo は -sysprops オプションを使用して、仮想マシン プロセスで指定された System.getProperties() の内容を出力できます。
また、このコマンドは、jps -v では確認できない、表示および指定されていない JVM パラメーターのシステム デフォルト値を表示することもできます。同時に、 jinfo コマンドは、 -flag name=value または -flag [+|-]name を使用して、実行時に変更できる
一部の仮想マシン パラメータを変更することにより、実行時にJVM パラメータを変更することもできます。

8. 信頼性および参照データには、システム操作ログ、スタック エラー情報、GC ログ、スレッド スナップショット、チューニング用のヒープ ダンプ スナップショットが含まれます。

	(1)系统运行日志:系统运行日志就是在程序代码中打印出的日志,描述了代码级别的系统运行轨迹(执行的方法、入参、返回值等),一般系统出现问题,系统运行日志是首先要查看的日志。
	
	(2)堆栈错误信息:当系统出现异常后,可以根据堆栈信息初步定位问题所在,比如根据“java.lang.OutOfMemoryError: Java heap space”可以判断是堆内存溢出;
   根据“java.lang.StackOverflowError”可以判断是栈溢出;根据“java.lang.OutOfMemoryError: PermGen space”可以判断是方法区溢出等。
   
	(3)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秒。

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

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

9. 概要:

(1) 目的:
	
       a.GC的时间足够的小
       b.GC的次数足够的少
       c.发生Full GC的周期足够的长
       
       前两个目前是相悖的,要想GC时间小必须要一个更小的堆,要保证GC次数足够少,必须保证一个更大的堆,我们只能取其平衡。
       更大的年轻代必然导致更小的年老代,大的年轻代会延长普通GC的周期,但会增加每次GC的时间;小的年老代会导致更频繁的Full GC
       更小的年轻代必然导致更大年老代,小的年轻代会导致普通GC很频繁,但每次的GC时间会更短;大的年老代会减少Full GC的频率
       如何选择应该依赖应用程序对象生命周期的分布情况:如果应用存在大量的临时对象,应该选择更大的年轻代;如果存在相对较多的持久对象,年老代应该适当增大。
       但很多应用都没有这样明显的特性,在抉择时应该根据以下两点:
        (A)本着Full GC尽量少的原则,让年老代尽量缓存常用对象,JVM的默认比例3:8也是这个道理
        (B)通过观察应用一段时间,看其他在峰值时年老代会占多少内存,在不影响FullGC的前提下,根据实际情况加大年轻代,比如可以把比例控制在1:1。但应该给年老代至少预留1/3的增长空间
        
(2) 途径:
		
		(A)将新对象预留在年轻代.
            众所周知,由于 Full GC 的成本远远高于 Minor GC,因此某些情况下需要尽可能将对象分配在年轻代,这在很多情况下是一    个明智的选择。
       虽然在大部分情况下,JVM 会尝试在 Eden 区分配对象,但是由于空间紧张等问题,很可能不得不将部分年轻对象提前向年老代压缩。因此,
       在 JVM 参数调优时可以为应用程序分配一个合理的年轻代空间,以最大限度避免新对象直接进入年老代的情况发生。
       可以尝试:-XX:TargetSurvivorRatio=90参数,这样可以提高 from 区的利用率,使 from 区使用到 90%时,再将对象送入年老代
       
		(B)让大对象进入年老代
            我们在大部分情况下都会选择将对象分配在年轻代。但是,对于占用内存较多的大对象而言,它的选择可能就不是这样的。
       因为大对象出现在年轻代很可能扰乱年轻代 GC,并破坏年轻代原有的对象结构。因为尝试在年轻代分配大对象,很可能导致空间不足,为了有足够的空间容纳大对象,
       JVM 不得不将年轻代中的年轻对象挪到年老代。因为大对象占用空间多,所以可能需要移动大量小的年轻对象进入年老代,这对 GC 相当不利。
       基于以上原因,可以将大对象直接分配到年老代,保持年轻代对象结构的完整性,这样可以提高 GC 的效率。如果一个大对象同时又是一个短命的对象,假设这种情况出现很频繁,
       那对于 GC 来说会是一场灾难。原本应该用于存放永久对象的年老代,被短命的对象塞满,这也意味着对堆空间进行了洗牌,扰乱了分代内存回收的基本思路。
       因此,在软件开发过程中,应该尽可能避免使用短命的大对象。
        可以使用参数:-XX:PetenureSizeThreshold 设置大对象直接进入年老代的阈值。当对象的大小超过这个值时,将直接在年老代分配。
        参数-XX:PetenureSizeThreshold 只对串行收集器和年轻代并行收集器有效,并行回收收集器不识别这个参数。
        
		(C)设置对象进入年老代的年龄
            堆中的每一个对象都有自己的年龄。一般情况下,年轻对象存放在年轻代,年老对象存放在年老代。为了做到这点,虚拟机为每个对象都维护一个年龄。
        如果对象在 Eden 区,经过一次 GC 后依然存活,则被移动到 Survivor 区中,对象年龄加 1。以后,如果对象每经过一次 GC 依然存活,则年龄再加 1。
        当对象年龄达到阈值时,就移入年老代,成为老年对象。
        -XX:MaxTenuringThreshold来设置,默认值是 15。虽然-XX:MaxTenuringThreshold 的值可能是 15 或者更大,但这不意味着新对象非要达到这个年龄才能进入年老代。
        事实上,对象实际进入年老代的年龄是虚拟机在运行时根据内存使用情况动态计算的,这个参数指定的是阈值年龄的最大值。
        即,实际晋升年老代年龄等于动态计算所得的年龄与-XX:MaxTenuringThreshold 中较小的那个。
        
		(D)稳定的 Java 堆 VS 动荡的 Java 堆
            一般来说,稳定的堆大小对垃圾回收是有利的。获得一个稳定的堆大小的方法是使-Xms 和-Xmx 的大小一致,即最大堆和最小堆 (初始堆)一样
        如果这样设置,系统在运行时堆大小理论上是恒定的,稳定的堆空间可以减少 GC 的次数。因此,很多服务端应用都会将最大堆和最小堆设置为相同的数值。
        但是,一个不稳定的堆并非毫无用处。稳定的堆大小虽然可以减少 GC 次数,但同时也增加了每次GC的时间。让堆大小在一个区间中震荡,在系统不需要使用大内存时,
        压缩堆空间,使 GC 应对一个较小的堆,可以加快单次 GC 的速度。基于这样的考虑,JVM 还提供了两个参数用于压缩和扩展堆空间:
        -XX:MinHeapFreeRatio 参数用来设置堆空间最小空闲比例,默认值是 40。当堆空间的空闲内存小于这个数值时,JVM 便会扩展堆空间。
        -XX:MaxHeapFreeRatio 参数用来设置堆空间最大空闲比例,默认值是 70。当堆空间的空闲内存大于这个数值时,便会压缩堆空间,得到一个较小的堆。
        当**-Xmx 和-Xms 相等时,-XX:MinHeapFreeRatio 和-XX:MaxHeapFreeRatio 两个参数无效**。
        
    	(E)增加吞吐量提升系统性能
            吞吐量优先的方案将会尽可能减少系统执行垃圾回收的总时间,故可以考虑关注系统吞吐量的并行回收收集器。在拥有高性能的计算机上,进行吞吐量优先优化,
            可以使用参数:
            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:设置年老代使用并行回收收集器。
            
    	(F)尝试使用大的内存分页
            在 Solaris 系统中,JVM 可以支持 Large Page Size 的使用。使用大的内存分页可以增强 CPU 的内存寻址能力,从而提升系统的性能
            –XX:+LargePageSizeInBytes:设置大页的大小。
            过大的内存分页会导致 JVM 在计算 Heap 内部分区(perm, new, old)内存占用比例时,会出现超出正常值的划分,最坏情况下某个区会多占用一个页的大小。
            
    	(G)使用非占有的垃圾回收器
            为降低应用软件的垃圾回收时的停顿,首先考虑的是使用关注系统停顿的 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,目的是让对象尽可能地保存在年轻代区域。

(3) すべての共通パラメータ
(A) ヒープメモリサイズを設定します

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

(B) 新世代のメモリ割り当てを設定する

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

(C) ガベージコレクターの設定

-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:使用并发收集器时,开启对年老代的压缩

(D) その他

 -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:+PrintGCTimeStamps 打应垃圾收集的情况
 -XX:+PrintGCApplicationConcurrentTime:打印每次垃圾回收前,程序未中断的执行时间。可与上面混合使用
 -XX:+PrintGCApplicationStoppedTime 打应垃圾收集时 , 系统的停顿时间
 -XX:+PrintGC 打印GC情况
 -XX:PrintHeapAtGC:打印GC前后的详细堆栈信息

印刷ログ設定:

-XX:+HeapDumpOnOutOfMemory:当程序发生内存溢出时,把当时的内存快照以文件形式进行转储(也可以直接用jmap命令转储程序运行时任意时刻的内存快照),事后对
            当时的内存使用情况进行分析
-XX:HeapDumpPath=/data/jvm/dumpfile.hprof
-XX:+PrintGCDetails 打应垃圾收集的情况
-Xloggc:/data/jvm/gc.log 打应垃圾收集的情况到哪个文件

おすすめ

転載: blog.csdn.net/w907645377/article/details/125325368