《深入理解Java虚拟机》(四)虚拟机性能监控与故障处理工具

2017-12-11 10:56:38来源:oschina作者:鹏磊人点击

分享

《深入理解Java虚拟机》(四)虚拟机性能监控与故障处理工具


虚拟机性能监控与故障处理工具 详解
4.1 概述

本文参考的是周志明的 《深入理解Java虚拟机》 第四章 ,为了整理思路,简单记录一下,方便后期查阅。


JDK本身提供了很多方便的JVM性能调优监控工具,除了集成式的VisualVM和jConsole外,还有jps、jstack、jmap、jhat、jstat、hprof等小巧的工具,本文希望能起抛砖引玉之用,让大家能开始对JVM性能调优的常用工具有所了解。


4.2 JDK的命令行工具

命令名称全称用途

jstatJVM Statistics Monitoring Tool用于收集Hotspot虚拟机各方面的运行数据
jpsJVM Process Status Tool显示指定系统内所有的HotSpot虚拟机进程
jinfoConfiguration Info for Java显示虚拟机配置信息
jmapJVM Memory Map生成虚拟机的内存转储快照,生成heapdump文件
jhatJVM Heap Dump Browser用于分析heapdump文件,它会建立一个HTTP/HTML服务器,让用户在浏览器上查看分析结果
jstackJVM Stack Trace显示虚拟机的线程快照4.2.1 jps:虚拟机进程状况工具
jps [options] [hostid]

> -l : 输出主类全名或jar路径
> -q : 只输出LVMID
> -m : 输出JVM启动时传递给main()的参数
> -v : 输出JVM启动时显示指定的JVM参数


$ jps -l
16256 sun.tools.jps.Jps
14904 org.jetbrains.jps.cmdline.Launcher
15016 com.ecej.esmart.gateway.service.impl.PengleiTest功能:可以列出正在运行的虚拟机进程,并线上虚拟机执行的主类名称及其本地虚拟机唯一ID(LVMID);
对于本地虚拟机来说,LVMID和操作系统的进程ID是一致的;
其他的工具通常都需要依赖jps获取LVMID;
主要选项:-q(只输出LVMID)、-m(输出传给main函数的参数)、-l(输出主类的全名)、-v(输出虚拟机启动JVM参数);
4.2.2 jstat:虚拟机统计信息监视工具

jstat(JVM statistics Monitoring)是用于监视虚拟机运行时状态信息的命令,它可以显示出虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据。


命令格式


$ jstat [option] LVMID [interval] [count]

参数


[option] : 操作参数
LVMID : 本地虚拟机进程ID
[interval] : 连续输出的时间间隔
[count] : 连续输出的次数

option 参数总览



选       项作       用

-class监视类装载、卸载数量、总空间以及类装载所耗费的时间
-gc监视Java堆状况,包括Eden区、两个Survivor区、、老年代、永久带等的容量、已用空间、GC时间合计等信息
-gccapacity监视内容基本与-gc相同,但输出主要关注Java堆各个区域使用到的最大、最小空间
-gcutil监视内容基本与-gc相同,但输出主要关注已使用的空间占总空间的百分比
-gccause与-gcutil功能一样,但是会额外输出导致上一次GC产生的原因
-gcnew监视新生代GC状况
-gcnewcapacity监视内容基本与-gcnew相同,但输出主要关注使用到的最大、最小空间
-gcold监视老年代GC状况
-gcoldcapacity监视内容基本与-gcold相同,但输出主要关注使用到的最大、最小空间
-gcpermcapacity输出永久代使用到的最大、最小空间
-compiler输出JIT编译器编译过的方法、耗时等信息
-printcompilation输出已经被JIT编译的方法

option 参数详解


-class


监视类装载、卸载数量、总空间以及耗费的时间


$ jstat -class 14988
LoadedBytesUnloadedBytes Time
5771152.8 0 0.00.17Loaded : 加载class的数量
Bytes : class字节大小
Unloaded : 未加载class的数量
Bytes : 未加载class的字节大小
Time : 加载时间

-compiler


输出JIT编译过的方法数量耗时等


$ jps -l -m
8657 org.apache.catalina.startup.Bootstrap start
12706 com.ecej.cust.service.run.Startup 60001
52132 sun.tools.jps.Jps -l -m
55671 customer.jar --server.port=8082 --log.home=/data/dubbo/logs/customer --log.level=info --log.stdout=0 ecej.ops.iswitch=1 --ecej.ops.port=80 --jmx.rmi.port=9991
$ jstat -compiler 55671
Compiled Failed Invalid Time FailedType FailedMethod
1378410 102.02 1 com/mysql/jdbc/AbandonedConnectionCleanupThread runCompiled : 编译数量
Failed : 编译失败数量
Invalid : 无效数量
Time : 编译耗时
FailedType : 失败类型
FailedMethod : 失败的方法

-gc


垃圾回收堆的行为统计,常用命令


$ jstat -gc 55671
S0CS1CS0US1UECEU OCOUMC MUCCSC CCSU YGC YGCTFGCFGCT GCT
512.0512.0 0.00.0 1285632.0 56336.6 259584.0 61064.8 74416.0 72873.0 8368.0 8015.01140.85410314.911 15.765S0C:第一个幸存区的大小
S1C:第二个幸存区的大小
S0U:第一个幸存区的使用大小
S1U:第二个幸存区的使用大小
EC:伊甸园区的大小
EU:伊甸园区的使用大小
OC:老年代大小
OU:老年代使用大小
MC:方法区大小
MU:方法区使用大小
CCSC:压缩类空间大小
CCSU:压缩类空间使用大小
YGC:年轻代垃圾回收次数
YGCT:年轻代垃圾回收消耗时间
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间
$ jstat -gc 55671 2000 20

这个命令意思就是每隔2000ms输出1262的gc情况,一共输出20次


-gccapacity


同-gc,不过还会输出Java堆各区域使用到的最大、最小空间


$ jstat -gccapacity 55671
NGCMNNGCMX NGC S0C S1CECOGCMNOGCMXOGCOCMCMN MCMXMC CCSMNCCSMX CCSCYGCFGC
84992.0 1360384.0 1287168.0512.0512.0 1285632.0 171008.02721280.0 259584.0 259584.00.0 1116160.074416.00.0 1048576.0 8368.0114 103NGCMN:新生代最小容量
NGCMX:新生代最大容量
NGC:当前新生代容量
S0C:第一个幸存区大小
S1C:第二个幸存区的大小
EC:伊甸园区的大小
OGCMN:老年代最小容量
OGCMX:老年代最大容量
OGC:当前老年代大小
OC:当前老年代大小
MCMN:最小元数据容量
MCMX:最大元数据容量
MC:当前元数据空间大小
CCSMN:最小压缩类空间大小
CCSMX:最大压缩类空间大小
CCSC:当前压缩类空间大小
YGC:年轻代gc次数
FGC:老年代GC次数 - NGCMN:新生代最小容量
NGCMX:新生代最大容量
NGC:当前新生代容量
S0C:第一个幸存区大小
S1C:第二个幸存区的大小
EC:伊甸园区的大小
OGCMN:老年代最小容量
OGCMX:老年代最大容量
OGC:当前老年代大小
OC:当前老年代大小
MCMN:最小元数据容量
MCMX:最大元数据容量
MC:当前元数据空间大小
CCSMN:最小压缩类空间大小
CCSMX:最大压缩类空间大小
CCSC:当前压缩类空间大小
YGC:年轻代gc次数
FGC:老年代GC次数

-gcutil


同-gc,不过输出的是已使用空间占总空间的百分比


$ jstat -gcutil 55671
S0 S1 EOM CCSYGC YGCTFGCFGCT GCT
0.00 0.00 6.2523.5297.9395.781140.854 103 14.911 15.765S0 -Heap上的Survivor space 0区已使用空间的百分比
S1 -Heap上的Survivor space 1区已使用空间的百分比
E -Heap上Eden space区已使用空间的百分比
O -Heap上的Old space区已使用空间的百分比
P -Perm space区已使用空间的百分比
YGC -从应用程序启动到采样时发生Yang GC 的次数
YGCT -从应用程序启动到采样时Yang GC所用的时间【单位秒】
FGC -从应用程序启动到采样时Full GC的次数
FGCT -从应用程序启动到采样时Full GC所用的时间
GCT -从应用程序启动到采样时用于垃圾回收的总时间【单位秒】

-gcnew


统计新生代的行为


$ jstat -gcnew 55671
S0CS1CS0US1U TT MTTDSSECEU YGC YGCT
512.0512.00.00.0 1515512.0 1285632.0 100094.51140.854S0C:第一个幸存区大小
S1C:第二个幸存区的大小
S0U:第一个幸存区的使用大小
S1U:第二个幸存区的使用大小
TT:对象在新生代存活的次数
MTT:对象在新生代存活的最大次数
DSS:期望的幸存区大小
EC:伊甸园区的大小
EU:伊甸园区的使用大小
YGC:年轻代垃圾回收次数
YGCT:年轻代垃圾回收消耗时间

-gcnewcapacity


新生代与其相应的内存空间的统计


$ jstat -gcnewcapacity55671
NGCMNNGCMXNGCS0CMX S0C S1CMX S1CECMX ECYGC FGC
84992.01360384.01287168.0 453120.0512.0 453120.0512.01359360.01285632.0 114 103NGCMN:新生代最小容量
NGCMX:新生代最大容量
NGC:当前新生代容量
S0CMX:最大幸存1区大小
S0C:当前幸存1区大小
S1CMX:最大幸存2区大小
S1C:当前幸存2区大小
ECMX:最大伊甸园区大小
EC:当前伊甸园区大小
YGC:年轻代垃圾回收次数
FGC:老年代回收次数

-gcold


统计旧生代的行为


$jstat -gcold 55671
MCMUCCSC CCSUOC OUYGCFGCFGCT GCT
74416.072873.0 8368.0 8015.0259584.0 61064.8114 103 14.911 15.765MC:方法区大小
MU:方法区使用大小
CCSC:压缩类空间大小
CCSU:压缩类空间使用大小
OC:老年代大小
OU:老年代使用大小
YGC:年轻代垃圾回收次数
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间

-gcoldcapacity


统计旧生代的大小和空间


$ jstat -gcoldcapacity 55671
OGCMNOGCMX OGCOCYGC FGCFGCT GCT
171008.0 2721280.0259584.0259584.0 116 105 15.170 16.033OGCMN:老年代最小容量
OGCMX:老年代最大容量
OGC:当前老年代大小
OC:老年代大小
YGC:年轻代垃圾回收次数
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间

-gcpermcapacity


永生代行为统计


> 在 JDK 8 删除永久代
> JDK 8 Java永久代去哪儿了
> 在Hotspot中的永久代码的内容的一部分移动到Java堆中,其余部分移动到本地内存


$ jstat -gcpermcapacity 28920
PGCMNPGCMXPGCPCYGC FGCFGCT GCT
1048576.02097152.01048576.01048576.0 4 00.0000.242

-printcompilation


hotspot编译方法统计


$ jstat -printcompilation 55671
CompiledSizeType Method
137851231 java/io/DataOutputStream writeCompiled:被执行的编译任务的数量
Size:方法字节码的字节数
Type:编译类型
Method:编译方法的类名和方法名。类名使用"/" 代替 "." 作为空间分隔符. 方法名是给出类的方法名. 格式是一致于HotSpot - XX:+PrintComplation 选项
4.2.3 jinfo:Java配置信息工具

jinfo(JVM Configuration info)这个命令作用是实时查看和调整虚拟机运行参数。
之前的jps -v口令只能查看到显示指定的参数,如果想要查看未被显示指定的参数的值就要使用jinfo口令


命令格式


jinfo [option] [args] LVMID

option参数


> - -flag : 输出指定args参数的值
> - -flags : 不需要args参数,输出所有JVM参数的值
> - -sysprops : 输出系统属性,等同于System.getProperties()


$ jinfo -flags 55671
Attaching to process ID 55671, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.65-b01
Non-default VM flags: -XX:CICompilerCount=4 -XX:InitialHeapSize=262144000 -XX:MaxHeapSize=4179623936 -XX:MaxNewSize=1393033216 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=87031808 -XX:OldSize=175112192 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseParallelGC
Command line:
4.2.4 jmap:Java内存映像工具

功能:用于生成堆转储快照(一般称为heapdump或dump文件)

其他可生成 heapdump 的方式:使用参数-XX:+HeapDumpOnOutOfMemoryError使用参数-XX:+HeapDumpOnCtrlBreak然后使用 Ctrl+Break 生成;Linux系统使用kill -3生成

另外它还可以查询 finalize 执行队列、Java堆和永久代的详细信息

命令格式


jmap [option] LVMID

option参数


dump : 生成堆转储快照
finalizerinfo : 显示在F-Queue队列等待Finalizer线程执行finalizer方法的对象
heap : 显示Java堆详细信息
histo : 显示堆中对象的统计信息
permstat :to print permanent generation statistics
F : 当-dump没有响应时,强制生成dump快照

-dump
常用格式


-dump::live,format=b,file= pid

dump堆到文件,format指定输出格式,live指明是活着的对象,file指定文件名


$ jmap -dump:live,format=b,file=penglei.hprof 55671
Dumping heap to /home/publish/penglei.hprof ...
Heap dump file created

penglei.hprof这个后缀是为了后续可以直接用MAT(Memory Anlysis Tool)打开。


-finalizerinfo


打印等待回收对象的信息


$ jmap -finalizerinfo 55671
Attaching to process ID 55671, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.65-b01
Number of objects pending for finalization: 0

可以看到当前F-QUEUE队列中并没有等待Finalizer线程执行finalizer方法的对象。


-heap


打印heap的概要信息,GC使用的算法,heap的配置及wise heap的使用情况,可以用此来判断内存目前的使用情况以及垃圾回收情况


$ jmap -heap 55671
Attaching to process ID 55671, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.65-b01
using thread-local object allocation.
Parallel GC with 8 thread(s)//GC 方式
Heap Configuration://堆内存初始化配置
MinHeapFreeRatio= 0 //对应jvm启动参数-XX:MinHeapFreeRatio设置JVM堆最小空闲比率(default 40)
MaxHeapFreeRatio= 100 //对应jvm启动参数 -XX:MaxHeapFreeRatio设置JVM堆最大空闲比率(default 70)
MaxHeapSize= 4179623936 (3986.0MB)//对应jvm启动参数-XX:MaxHeapSize=设置JVM堆的最大大小
NewSize= 87031808 (83.0MB)//对应jvm启动参数-XX:NewSize=设置JVM堆的‘新生代’的默认大小
MaxNewSize = 1393033216 (1328.5MB)//对应jvm启动参数-XX:MaxNewSize=设置JVM堆的‘新生代’的最大大小
OldSize= 175112192 (167.0MB)//对应jvm启动参数-XX:OldSize=:设置JVM堆的‘老生代’的大小
NewRatio = 2//对应jvm启动参数-XX:NewRatio=:‘新生代’和‘老生代’的大小比率
SurvivorRatio = 8//对应jvm启动参数-XX:SurvivorRatio=设置年轻代中Eden区与Survivor区的大小比值
MetaspaceSize = 21807104 (20.796875MB)//对应jvm启动参数--XX:MetaspaceSize是分配给类元数据空间
CompressedClassSpaceSize = 1073741824 (1024.0MB)//对应jvm启动参数-XX:CompressedClassSpaceSize 默认也有1G,我能猜到metaspace的作者不希望出现它相关的OOM问题
MaxMetaspaceSize= 17592186044415 MB//对应jvm启动参数XX:MaxMetaspaceSize设置最大的本地内存类员工间可用于垃圾回收。默认没有限制,也就是说你的系统内存上限是多少它就是多少如果没有指定的话,元空间会根据应用程序运行时的需要动态地调整大小。
G1HeapRegionSize= 0 (0.0MB)//当使用G1收集器时,设置java堆被分割的大小。这个大小范围在1M到32M之间
Heap Usage://堆内存使用情况
PS Young Generation
Eden Space://Eden区内存分布
capacity = 1317011456 (1256.0MB)//Eden区总容量
used = 46816712 (44.64789581298828MB)//Eden区已使用
free = 1270194744 (1211.3521041870117MB)//Eden区剩余容量
3.554768774919449% used //Eden区使用比率
From Space://其中一个Survivor区的内存分布
capacity = 524288 (0.5MB)
used = 0 (0.0MB)
free = 524288 (0.5MB)
0.0% used
To Space://另一个Survivor区的内存分布
capacity = 524288 (0.5MB)
used = 0 (0.0MB)
free = 524288 (0.5MB)
0.0% used
PS Old Generation//当前的Old区内存分布
capacity = 312999936 (298.5MB)
used = 62510688 (59.614837646484375MB)
free = 250489248 (238.88516235351562MB)
19.971469898319725% used
32160 interned Strings occupying 3634120 bytes.
[publish@YZ-PTEST-CUS-WEB-01 ~]$

可以很清楚的看到Java堆中各个区域目前的情况。


4.2.5 jhat:虚拟机堆转储快照分析工具

功能:用于分析jmap生成的heapdump。其内置了一个微型的HTTP服务器,可以在浏览器查看分析结果;

实际很少用jhat,主要有两个原因:一是分析工程会耗用服务器资源;功能相对BisualVM、IBM HeapAnalyzer较为简陋;

命令格式


jhat [dumpfile]

参数


-stack false|true
关闭对象分配调用栈跟踪(tracking object allocation call stack)。 如果分配位置信息在堆转储中不可用. 则必须将此标志设置为 false. 默认值为 true.>
-refs false|true
关闭对象引用跟踪(tracking of references to objects)。 默认值为 true. 默认情况下, 返回的指针是指向其他特定对象的对象,如反向链接或输入引用(referrers or incoming references), 会统计/计算堆中的所有对象。>
-port port-number
设置 jhat HTTP server 的端口号. 默认值 7000.>
-exclude exclude-file
指定对象查询时需要排除的数据成员列表文件(a file that lists data members that should be excluded from the reachable objects query)。 例如, 如果文件列列出了 java.lang.String.value , 那么当从某个特定对象 Object o 计算可达的对象列表时, 引用路径涉及 java.lang.String.value 的都会被排除。>
-baseline exclude-file
指定一个基准堆转储(baseline heap dump)。 在两个 heap dumps 中有相同 object ID 的对象会被标记为不是新的(marked as not being new). 其他对象被标记为新的(new). 在比较两个不同的堆转储时很有用.>
-debug int
设置 debug 级别. 0 表示不输出调试信息。 值越大则表示输出更详细的 debug 信息.>
-version
启动后只显示版本信息就退出>
-J< flag >
因为 jhat 命令实际上会启动一个JVM来执行, 通过 -J 可以在启动JVM时传入一些启动参数. 例如, -J-Xmx512m 则指定运行 jhat 的Java虚拟机使用的最大堆内存为 512 MB. 如果需要使用多个JVM启动参数,则传入多个 -Jxxxxxx.
$ jhat -J-Xmx512m dump.hprof
Reading from dump.hprof...
Dump file created Mon Jul 31 23:46:31 CST 2017
Snapshot read, resolving...
Resolving 1285013 objects...
Chasing references, expect 257 dots.................................................................................................................................................................................................................................................................
Eliminating duplicate references.................................................................................................................................................................................................................................................................
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.

中间的-J-Xmx512m是在dump快照很大的情况下分配512M内存去启动HTTP服务器,运行完之后就可在浏览器打开Http://localhost:7000进行快照分析
堆快照分析主要在最后面的Heap Histogram里,里面根据class列出了dump的时候所有存活对象。


4.2.6 jstack:Java堆栈跟踪工具

jstack用于生成java虚拟机当前时刻的线程快照。线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等。 线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做什么事情,或者等待什么资源。 如果java程序崩溃生成core文件,jstack工具可以用来获得core文件的java stack和native stack的信息,从而可以轻松地知道java程序是如何崩溃和在程序何处发生问题。另外,jstack工具还可以附属到正在运行的java程序中,看到当时运行的java程序的java stack和native stack的信息, 如果现在运行的java程序呈现hung的状态,jstack是非常有用的。


命令格式


jstack [option] LVMID

option参数


-F : 当正常输出请求不被响应时,强制输出线程堆栈
-l : 除堆栈外,显示关于锁的附加信息
-m : 如果调用到本地方法的话,可以显示C/C++的堆栈
$ jstack -l 55671|more
2017-08-01 00:20:58
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.65-b01 mixed mode):
"DubboClientHandler-10.32.32.31:7070-thread-6208" #13942 daemon prio=5 os_prio=0 tid=0x00007f4a40002800 nid=0xd5f1 waiting on condition [0x00007f4af0b5f000]
java.lang.Thread.State: TIMED_WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for<0x00000006ca25a240> (a java.util.concurrent.SynchronousQueue$TransferStack)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:362)
at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:941)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1066)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Locked ownable synchronizers:
- None
"DubboClientHandler-10.32.32.54:60036-thread-1219" #13941 daemon prio=5 os_prio=0 tid=0x00007f4a640f4800 nid=0xd5ec waiting on condition [0x00007f4ae818f000]
java.lang.Thread.State: TIMED_WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for<0x00000006ca76a638> (a java.util.concurrent.SynchronousQueue$TransferStack)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:362)
at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:941)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1066)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Locked ownable synchronizers:
- None
--More--

这里有一篇文章解释的很好
分析打印出的文件内容


《深入理解Java虚拟机:JVM高级特性与最佳实践_周志明.高清扫描版.pdf》


下载地址:链接:http://pan.baidu.com/s/1miBQCBY 密码:9kbn


推荐阅读

《深入理解Java虚拟机》(一)Java虚拟机发展史


《深入理解Java虚拟机》(二)Java虚拟机运行时数据区


《深入理解Java虚拟机》(三)垃圾收集器与内存分配策略


《深入理解Java虚拟机》(四)虚拟机性能监控与故障处理工具


《深入理解Java虚拟机》(五)JVM调优 - 工具


《深入理解Java虚拟机》(六)堆内存使用分析,GC 日志解读


参考


本文参考-纯洁的微笑-jvm调优-命令篇


命令全部都自己试验了一遍


参考-纯洁的微笑-jvm调优-命令篇


Contact
作者:鹏磊
出处:http://www.ymq.io
Email:admin@souyunku.com
GitHub:https://github.com/souyunku
Segment Fault:http://sf.gg/blog/souyunku
版权归作者所有,转载请注明出处
Wechat:关注公众号,搜云库,分享技术,分享生活

关注公众号-搜云库

微信扫一扫

第七城市微信公众平台