一、jps
dbq@mac:~$ jps
50053 TIS_FullGC_Problem01
48599 Jps
92253
二、jinfo
列出当前jvm的详细信息
jinfo 50053
dbq@mac:~$ jinfo 50053
Attaching to process ID 50053, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.131-b11
Java System Properties:
java.runtime.name = Java(TM) SE Runtime Environment
java.vm.version = 25.131-b11
sun.boot.library.path = /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib
gopherProxySet = false
java.vendor.url = http://java.oracle.com/
java.vm.vendor = Oracle Corporation
path.separator = :
file.encoding.pkg = sun.io
java.vm.name = Java HotSpot(TM) 64-Bit Server VM
sun.os.patch.level = unknown
sun.java.launcher = SUN_STANDARD
user.country = CN
user.dir = /Users/dbq/Documents/git/GCTest/out/production/GCTest
java.vm.specification.name = Java Virtual Machine Specification
java.runtime.version = 1.8.0_131-b11
java.awt.graphicsenv = sun.awt.CGraphicsEnvironment
os.arch = x86_64
java.endorsed.dirs = /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/endorsed
line.separator =
java.io.tmpdir = /var/folders/fg/7tr0w_412q7ffqmyhy48jnn40000gn/T/
java.vm.specification.vendor = Oracle Corporation
os.name = Mac OS X
sun.jnu.encoding = UTF-8
java.library.path = /Users/dbq/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:.
java.specification.name = Java Platform API Specification
java.class.version = 52.0
sun.management.compiler = HotSpot 64-Bit Tiered Compilers
os.version = 10.13.1
http.nonProxyHosts = local„ÄÅ169.254/16|*.local„ÄÅ169.254/16
user.home = /Users/dbq
user.timezone =
java.awt.printerjob = sun.lwawt.macosx.CPrinterJob
file.encoding = UTF-8
java.specification.version = 1.8
user.name = dbq
java.class.path = .
java.vm.specification.version = 1.8
sun.arch.data.model = 64
sun.java.command = com.mashibing.jvm.gc.TIS_FullGC_Problem01
java.home = /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre
user.language = zh
java.specification.vendor = Oracle Corporation
user.language.format = en
awt.toolkit = sun.lwawt.macosx.LWCToolkit
java.vm.info = mixed mode
java.version = 1.8.0_131
java.ext.dirs = /Users/dbq/Library/Java/Extensions:/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/ext:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java
sun.boot.class.path = /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/sunrsasign.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/classes
java.vendor = Oracle Corporation
file.separator = /
java.vendor.url.bug = http://bugreport.sun.com/bugreport/
sun.io.unicode.encoding = UnicodeBig
sun.cpu.endian = little
socksNonProxyHosts = local„ÄÅ169.254/16|*.local„ÄÅ169.254/16
ftp.nonProxyHosts = local„ÄÅ169.254/16|*.local„ÄÅ169.254/16
sun.cpu.isalist =
VM Flags:
Non-default VM flags: -XX:CICompilerCount=3 -XX:InitialHeapSize=209715200 -XX:MaxHeapSize=209715200 -XX:MaxNewSize=69730304 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=69730304 -XX:OldSize=139984896 -XX:+PrintGC -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseParallelGC
Command line: -Xms200M -Xmx200M -XX:+PrintGC
VM Flags:jvm参数信息
三、jstat
打印java的统计信息
jstat -gc pid 打印gc的统计信息
dbq@mac:~$ jstat -gc 50053
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
8192.0 8192.0 0.0 8180.3 50688.0 39484.0 136704.0 78432.0 4864.0 4024.3 512.0 441.3 5 0.184 0 0.000 0.184
也可以动态的统计
jstat -gc 48369 500 每500ms打印一次统计信息
dbq@mac:~$ jstat -gc 50053 500
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
22528.0 22528.0 0.0 15684.3 23040.0 17325.8 136704.0 97600.1 4864.0 4024.3 512.0 441.3 7 0.266 0 0.000 0.266
22528.0 22528.0 0.0 15684.3 23040.0 17478.7 136704.0 97600.1 4864.0 4024.3 512.0 441.3 7 0.266 0 0.000 0.266
22528.0 22528.0 0.0 15684.3 23040.0 17936.7 136704.0 97600.1 4864.0 4024.3 512.0 441.3 7 0.266 0 0.000 0.266
22528.0 22528.0 0.0 15684.3 23040.0 18456.8 136704.0 97600.1 4864.0 4024.3 512.0 441.3 7 0.266 0 0.000 0.266
22528.0 22528.0 0.0 15684.3 23040.0 18784.2 136704.0 97600.1 4864.0 4024.3 512.0 441.3 7 0.266 0 0.000 0.266
22528.0 22528.0 0.0 15684.3 23040.0 18784.2 136704.0 97600.1 4864.0 4024.3 512.0 441.3 7 0.266 0 0.000 0.266
22528.0 22528.0 0.0 15684.3 23040.0 19020.5 136704.0 97600.1 4864.0 4024.3 512.0 441.3 7 0.266 0 0.000 0.266
查看GC频率
ps -eo pid,tty,user,comm,lstart,etime | grep 24019
dbq@mac:$ ps -eo pid,tty,user,comm,lstart,etime | grep 40536
40536 ttys001 dbq java 一 3/ 1 08:30:05 2021 02:20
GC频率 = 进程运行时间/GC次数
四、垃圾回收信息的解释
之前由于添加了printGC,所以会打印gc回收信息,一般循环打印,并指定大小
GC指的是YGC,从多少k回收到多少k,相减就是回收的内存大小
FullGC
dbq@mac:~/Documents/git/GCTest/out/production/GCTest$ java -Xms200M -Xmx200M -XX:+PrintGC com.mashibing.jvm.gc.TIS_FullGC_Problem01
[GC (Allocation Failure) 51712K->1256K(196608K), 0.0023883 secs]
[GC (Allocation Failure) 52968K->23238K(196608K), 0.0523418 secs]
[GC (Allocation Failure) 74950K->44536K(196608K), 0.0491664 secs]
[GC (Allocation Failure) 96248K->67248K(196608K), 0.0435336 secs]
[GC (Allocation Failure) 118960K->86612K(195584K), 0.0364209 secs]
[GC (Allocation Failure) 137300K->105244K(167936K), 0.0478008 secs]
[GC (Allocation Failure) 128284K->113284K(182272K), 0.0342078 secs]
[GC (Allocation Failure) 136324K->120780K(182272K), 0.0440687 secs]
[GC (Allocation Failure) 143820K->131652K(182272K), 0.0488463 secs]
[Full GC (Ergonomics) 131652K->126984K(182272K), 0.9244073 secs]
[Full GC (Ergonomics) 150024K->135637K(182272K), 0.4714047 secs]
[Full GC (Ergonomics) 158677K->143194K(182272K), 0.5033654 secs]
[Full GC (Ergonomics) 159727K->147805K(182272K), 0.5497019 secs]
[Full GC (Ergonomics) 159727K->151623K(182272K), 0.5586325 secs]
[Full GC (Ergonomics) 159727K->154162K(182272K), 0.5261450 secs]
[Full GC (Ergonomics) 159727K->155930K(182272K), 0.5602670 secs]
[Full GC (Ergonomics) 159727K->157209K(182272K), 0.5733866 secs]
五、top
top命令可以查看哪些进程占用资源比较多
六、top -Hp pid
top命令可以查看进程中线程占用资源情况
由于mac下 -Hp不支持,这是linux下其他进程的线程信息
top - 15:30:44 up 117 days, 14 min, 1 user, load average: 0.00, 0.00, 0.00
Threads: 52 total, 0 running, 52 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.3 us, 0.2 sy, 0.0 ni, 99.3 id, 0.0 wa, 0.2 hi, 0.0 si, 0.0 st
MiB Mem : 3637.6 total, 327.2 free, 993.9 used, 2316.5 buff/cache
MiB Swap: 0.0 total, 0.0 free, 0.0 used. 2387.5 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
3489 root 20 0 3497204 535276 18008 S 0.7 14.4 606:02.57 System Clock
3464 root 20 0 3497204 535276 18008 S 0.0 14.4 0:00.00 java
3467 root 20 0 3497204 535276 18008 S 0.0 14.4 0:07.24 java
3469 root 20 0 3497204 535276 18008 S 0.0 14.4 0:09.84 java
3470 root 20 0 3497204 535276 18008 S 0.0 14.4 0:09.88 java
3471 root 20 0 3497204 535276 18008 S 0.0 14.4 1:20.66 VM Thread
3472 root 20 0 3497204 535276 18008 S 0.0 14.4 0:00.03 Reference Handl
3473 root 20 0 3497204 535276 18008 S 0.0 14.4 0:00.01 Finalizer
3474 root 20 0 3497204 535276 18008 S 0.0 14.4 0:00.00 Signal Dispatch
3475 root 20 0 3497204 535276 18008 S 0.0 14.4 0:42.07 C2 CompilerThre
3476 root 20 0 3497204 535276 18008 S 0.0 14.4 0:19.02 C1 CompilerThre
3477 root 20 0 3497204 535276 18008 S 0.0 14.4 0:00.00 Service Thread
3478 root 20 0 3497204 535276 18008 S 0.0 14.4 25:44.90 VM Periodic Tas
3481 root 20 0 3497204 535276 18008 S 0.0 14.4 2:17.25 Catalina-utilit
3482 root 20 0 3497204 535276 18008 S 0.0 14.4 2:18.40 Catalina-utilit
七、jstack 50053 | more (必须掌握)
dbq@mac:~$ jstack 50053 | more
2021-02-27 15:32:08
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.131-b11 mixed mode):
"pool-1-thread-71" #81 prio=5 os_prio=31 tid=0x00007fbd7313c800 nid=0x1a07 waiting on condition [0x00007000081fb000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000007b9673f58> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireInterruptibly(AbstractQueuedSynchronizer.java:897)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1222)
at java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:335)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1076)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
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:748)
"Attach Listener" #80 daemon prio=9 os_prio=31 tid=0x00007fbd7287d000 nid=0x6c0b waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"pool-1-thread-70" #79 prio=5 os_prio=31 tid=0x00007fbd7313c000 nid=0x6007 waiting on condition [0x0000700005983000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000007b9673f58> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireInterruptibly(AbstractQueuedSynchronizer.java:897)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1222)
at java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:335)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1076)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
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:748)
"pool-1-thread-69" #78 prio=5 os_prio=31 tid=0x00007fbd71868800 nid=0x5807 waiting on condition [0x0000700005577000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000007b9673f58> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireInterruptibly(AbstractQueuedSynchronizer.java:897)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1222)
at java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:335)
八、jmap
jmap -histo pid
显示对象的内存图
当我们的程序频繁GC时
Exception in thread "pool-1-thread-51" java.lang.OutOfMemoryError: GC overhead limit exceeded
[Full GC (Ergonomics) 159584K->159581K(182272K), 0.5506696 secs]
[Full GC (Ergonomics) 159584K->159581K(182272K), 0.5855513 secs]
[Full GC (Ergonomics) 159584K->159581K(182272K), 0.5552056 secs]
[Full GC (Ergonomics) 159584K->159581K(182272K), 0.5426389 secs]
可以通过这个命令查看哪些对象不被回收 (head:列出前20行)
可以多次运行该命令观察某对象是否持续增大,说明该对象不断在产生,不被回收
dbq@mac:~$ jmap -histo 52272 | head -20
对象数 占用内存字节数
num #instances #bytes class name
----------------------------------------------
1: 638662 20437184 java.util.concurrent.locks.AbstractQueuedSynchronizer$Node
2: 283400 20404800 java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask
3: 283426 11337040 java.math.BigDecimal
4: 283400 9068800 com.mashibing.jvm.gc.TIS_FullGC_Problem01$CardInfo
5: 283400 6801600 java.util.Date
6: 283400 6801600 java.util.concurrent.Executors$RunnableAdapter
7: 283400 4534400 com.mashibing.jvm.gc.TIS_FullGC_Problem01$$Lambda$2/1826771953
8: 4726 3946808 [I
9: 2 2662728 [Ljava.util.concurrent.RunnableScheduledFuture;
10: 7312 1308256 [Ljava.lang.Object;
11: 1901 152072 [C
12: 747 85552 java.lang.Class
13: 1889 45336 java.lang.String
14: 42 26080 [B
15: 929 22296 java.util.ArrayList
16: 57 21432 java.lang.Thread
17: 185 13320 java.lang.reflect.Field
jmap还可以把整个对导出到文件,可以离线分析
format=b标识导出格式为二进制
jmap -dump:format=b,file=/User/dbq/Documents/20201108.hprof 52272
线上一般不容许jmap或者远程连接,所以需要在java启动时加上-XX:+HeapDumpOnOutOfMemoryError参数
TCPCopy:网易出的一款软件,可以将线上生产环境的tcp拷贝一份到本地,一般用于线上流量压测本地环境
九、Arthas 开源 Java 诊断工具(阿里出的)
启动并将arthas挂载到我们的程序上
dbq@mac:~/Documents/tools/jvm性能诊断工具/arthas/arthas-packaging-3.1.1$ sh as.sh
Arthas script version: 3.1.1
[INFO] JAVA_HOME: /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home
Found existing java process, please choose one and hit RETURN.
* [1]: 52193 org.jetbrains.jps.cmdline.Launcher
[2]: 56573 com.mashibing.jvm.gc.TIS_FullGC_Problem01
[3]: 52142
2
Arthas home: /Users/dbq/Documents/tools/jvm性能诊断工具/arthas/arthas-packaging-3.1.1
Calculating attach execution time...
Attaching to 56573 using version /Users/dbq/Documents/tools/jvm性能诊断工具/arthas/arthas-packaging-3.1.1...
real 0m1.138s
user 0m0.375s
sys 0m0.052s
Attach success.
telnet connecting to arthas server... current timestamp is 1614413542
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
,---. ,------. ,--------.,--. ,--. ,---. ,---.
/ O \ | .--. ''--. .--'| '--' | / O \ ' .-'
| .-. || '--'.' | | | .--. || .-. |`. `-.
| | | || |\ \ | | | | | || | | |.-' |
`--' `--'`--' '--' `--' `--' `--'`--' `--'`-----'
wiki https://alibaba.github.io/arthas
tutorials https://alibaba.github.io/arthas/arthas-tutorials
version 3.1.1
pid 56573
time 2021-02-27 16:12:22
$
dashboard命令:仪表盘,可以显示线程的情况
为了便于观察,我设置了线程名称
: $ thread 类似jstack
thread 线程号,可以把该线程的详细信息打出来
"GCTest-Thead" Id=1 TIMED_WAITING
at java.lang.Thread.sleep(Native Method)
at com.mashibing.jvm.gc.TIS_FullGC_Problem01.main(TIS_FullGC_Problem01.java:35)
Affect(row-cnt:0) cost in 16 ms.
$
thread -b: 可以查看是否有死锁
$ thread -b
No most blocking thread found!
Affect(row-cnt:0) cost in 18 ms.
$
附录一(马士兵视频中的一些问题)
解决过哪些实际调优经验?
OOM