JVM调优工具命令的使用

常用工具命令

命令描述
jps与linux的ps类似,用来显示本地的java进程,可以查看本地运行着几个java程序,并显示他们的进程号
jstack查看jvm 线程运行状态,是否有死锁现象等等信息
jinfo可以输出并修改运行时的java 进程的opts
jstat一个极强的监视VM 内存工具。可以用来监视VM 内存内的各种堆和非堆的大小及其内存使用量
jmap打印出某个java 进程(使用pid)内存内的所有’对象’的情况(如:产生那些对象,及其数量)
jhat对dump文件进行分析
mat一个基于Eclipse的内存分析工具,是一个快速、功能丰富的JAVA heap分析工具

JSTAT

	jstat工具特别强大,有众多的可选项,详细查看堆内各个部分的使用量,以及加载类的数量。
  • jstat -help
Usage: jstat -help|-options
       jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]

Definitions:
  <option>      An option reported by the -options option
  <vmid>        Virtual Machine Identifier. A vmid takes the following form:
                     <lvmid>[@<hostname>[:<port>]]
                Where <lvmid> is the local vm identifier for the target
                Java virtual machine, typically a process id; <hostname> is
                the name of the host running the target Java virtual machine;
                and <port> is the port number for the rmiregistry on the
                target host. See the jvmstat documentation for a more complete
                description of the Virtual Machine Identifier.
  <lines>       Number of samples between header lines.
  <interval>    Sampling interval. The following forms are allowed:
                    <n>["ms"|"s"]
                Where <n> is an integer and the suffix specifies the units as
                milliseconds("ms") or seconds("s"). The default units are "ms".
  <count>       Number of samples to take before terminating.
  -J<flag>      Pass <flag> directly to the runtime system.
  • jstat -options <pId>
-class 查看class加载统计,显示加载class的数量,及所占空间等信息
-compiler 查看编译统计,显示VM 实时编译的数量等信息
-gc 垃圾回收统计,可以显示gc信息,查看gc的次数,时间
-gccapacity 堆内存统计,三代(young,old,perm)内存使用和占用大小
-gccause 
-gcmetacapacity 
-gcnew 新生代垃圾回收统计
-gcnewcapacity 新生代内存统计
-gcold 老年代垃圾回收统计
-gcoldcapacity
-gcutil 统计一次gc情况
-printcompilation

JINFO

	jinfo是JDK自带命令,可以用来查看正在运行的java应用程序的扩展参数,包括Java System属性和JVM命令行参数。也可以动态的修改正在运行的JVM 一些参数。当系统崩溃时,jinfo可以从core文件里面知道崩溃的Java应用程序的配置信息
  • jinfo -help
Usage:
    jinfo [option] <pid>
        (to connect to running process)
    jinfo [option] <executable <core>
        (to connect to a core file)
    jinfo [option] [server_id@]<remote server IP or hostname>
        (to connect to remote debug server)

where <option> is one of:
    -flag <name>         to print the value of the named VM flag
    -flag [+|-]<name>    to enable or disable the named VM flag
    -flag <name>=<value> to set the named VM flag to the given value
    -flags               to print VM flags
    -sysprops            to print Java system properties
    <no option>          to print both of the above
    -h | -help           to print this help message
  • jinfo <pId> : 输出当前jvm进程的全部参数和系统属性
com.sun.management.jmxremote =
java.vm.specification.version = 1.8
sun.arch.data.model = 64
sun.java.command = cn.ybzy.demo.DemoApplication
java.home = D:\Development\Java\jdk1.8\jre
user.language = zh
java.specification.vendor = Oracle Corporation
awt.toolkit = sun.awt.windows.WToolkit
java.vm.info = mixed mode
java.version = 1.8.0_271
java.ext.dirs = D:\Development\Java\jdk1.8\jre\lib\ext;C:\Windows\Sun\Java\lib\ext
sun.boot.class.path = D:\Development\Java\jdk1.8\jre\lib\resources.jar;D:\Development\Java\jdk1.8\jre\lib\rt.jar;D:\Development\Java\jdk1.8\jre\lib\sunrsasign.jar;D:\Development\Java\jdk1.8\jre\lib\jsse.jar;D:\Development\Java\jdk1.8\jre\lib\jce.jar;D:\Development\Java\jdk1.8\jre\lib\charsets.jar;D:\Development\Java\jdk1.8\jre\lib\jfr.jar;D:\Development\Java\jdk1.8\jre\classes
java.awt.headless = true
java.vendor = Oracle Corporation
spring.application.admin.enabled = true
file.separator = \
java.vendor.url.bug = http://bugreport.sun.com/bugreport/
sun.io.unicode.encoding = UnicodeLittle
sun.cpu.endian = little
sun.desktop = windows
sun.cpu.isalist = amd64

VM Flags:
Non-default VM flags: -XX:-BytecodeVerificationLocal -XX:-BytecodeVerificationRemote -XX:CICompilerCount=4 -XX:InitialHeapSize=234881024 -XX:+ManagementServer -XX:MaxHeapSize=3728736256 -XX:MaxNewSize=1242562560 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=78118912 -XX:OldSize=156762112 -XX:TieredStopAtLevel=1 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
Command line:  -XX:TieredStopAtLevel=1 -Xverify:none -Dspring.output.ansi.enabled=always -Dcom.sun.management.jmxremote -Dspring.jmx.enabled=true -Dspring.liveBeansView.mbeanDomain -Dspring.application.admin.enabled=true -javaagent:D:\Development\JetBrains\IntelliJ IDEA 2022.1.2\lib\idea_rt.jar=4556:D:\Development\JetBrains\IntelliJ IDEA 2022.1.2\bin -Dfile.encoding=UTF-8
  • jinfo -flag name <pId> : 可以查看指定的jvm 参数的值;打印结果:-无此参数,+有
jinfo -flag -UseParallelGC 11304
-XX:+UseParallelGC
  • jinfo -flag [+|-]name <pid> :开启或者关闭对应名称的参数(无需重启虚拟机)
jinfo -flag -UseParallelGC 11304
jinfo -flag +UseParallelGC 11304
  • jinfo -flag name=value <pId> :修改指定参数的值
  • jinfo -flags <pId> :输出全部的参数
Attaching to process ID 11304, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.271-b09
Non-default VM flags: -XX:-BytecodeVerificationLocal -XX:-BytecodeVerificationRemote -XX:CICompilerCount=4 -XX:InitialHeapSize=234881024 -XX:+ManagementServer -XX:MaxHeapSize=3728736256 -XX:MaxNewSize=1242562560 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=78118912 -XX:OldSize=156762112 -XX:TieredStopAtLevel=1 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
Command line:  -XX:TieredStopAtLevel=1 -Xverify:none -Dspring.output.ansi.enabled=always -Dcom.sun.management.jmxremote -Dspring.jmx.enabled=true -Dspring.liveBeansView.mbeanDomain -Dspring.application.admin.enabled=true -javaagent:D:\Development\JetBrains\IntelliJ IDEA 2022.1.2\lib\idea_rt.jar=4556:D:\Development\JetBrains\IntelliJ IDEA 2022.1.2\bin -Dfile.encoding=UTF-8
  • jinfo -sysprops <pId> :输出当前jvm进行的全部的系统属性
com.sun.management.jmxremote =
java.vm.specification.version = 1.8
sun.arch.data.model = 64
sun.java.command = cn.ybzy.demo.DemoApplication
java.home = D:\Development\Java\jdk1.8\jre
user.language = zh
java.specification.vendor = Oracle Corporation
awt.toolkit = sun.awt.windows.WToolkit
java.vm.info = mixed mode
java.version = 1.8.0_271
java.ext.dirs = D:\Development\Java\jdk1.8\jre\lib\ext;C:\Windows\Sun\Java\lib\ext
sun.boot.class.path = D:\Development\Java\jdk1.8\jre\lib\resources.jar;D:\Development\Java\jdk1.8\jre\lib\rt.jar;D:\Development\Java\jdk1.8\jre\lib\sunrsasign.jar;D:\Development\Java\jdk1.8\jre\lib\jsse.jar;D:\Development\Java\jdk1.8\jre\lib\jce.jar;D:\Development\Java\jdk1.8\jre\lib\charsets.jar;D:\Development\Java\jdk1.8\jre\lib\jfr.jar;D:\Development\Java\jdk1.8\jre\classes
java.awt.headless = true
java.vendor = Oracle Corporation
spring.application.admin.enabled = true
file.separator = \
java.vendor.url.bug = http://bugreport.sun.com/bugreport/
sun.io.unicode.encoding = UnicodeLittle
sun.cpu.endian = little
sun.desktop = windows
sun.cpu.isalist = amd64

JMAP

	jstat可以对jvm堆的内存进行统计分析,而jjmap可以获取到更加详细的内容,如:内存使用情况的汇总、对内存溢出的定位与分析

	jmap可以生成heap dump文件,也可以查看堆内对象分析内存信息等,如果不使用这个命令,还可以使用-XX:+HeapDumpOnOutOfMemoryError参数来让虚拟机出现OOM的时候自动生成dump文件。
  • jmap -help
Usage:
    jmap [option] <pid>
        (to connect to running process)
    jmap [option] <executable <core>
        (to connect to a core file)
    jmap [option] [server_id@]<remote server IP or hostname>
        (to connect to remote debug server)

where <option> is one of:
    <none>               to print same info as Solaris pmap
    -heap                to print java heap summary
    -histo[:live]        to print histogram of java object heap; if the "live"
                         suboption is specified, only count live objects
    -clstats             to print class loader statistics
    -finalizerinfo       to print information on objects awaiting finalization
    -dump:<dump-options> to dump java heap in hprof binary format
                         dump-options:
                           live         dump only live objects; if not specified,
                                        all objects in the heap are dumped.
                           format=b     binary format
                           file=<file>  dump heap to <file>
                         Example: jmap -dump:live,format=b,file=heap.bin <pid>
    -F                   force. Use with -dump:<dump-options> <pid> or -histo
                         to force a heap dump or histogram when <pid> does not
                         respond. The "live" suboption is not supported
                         in this mode.
    -h | -help           to print this help message
    -J<flag>             to pass <flag> directly to the runtime system
  • jmap -dump:live,format=b,file=dump.hprof pid : 将jvm当前内存中的情况dump到文件中,然后对它进行分析。format指定输出格式,live指明是活着的对象,file指定文件名。
Dumping heap to C:\Users\Admin\dump.hprof ...
Heap dump file created
  • jmap -heap pid : 查看内存使用情况,打印heap的概要信息,GC使用的算法,heap的配置和使用情况,可以用此来判断内存目前的使用情况以及垃圾回收情况
Attaching to process ID 11304, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.271-b09

using thread-local object allocation.
Parallel GC with 10 thread(s)

Heap Configuration:
   MinHeapFreeRatio         = 0
   MaxHeapFreeRatio         = 100
   MaxHeapSize              = 3728736256 (3556.0MB)
   NewSize                  = 78118912 (74.5MB)
   MaxNewSize               = 1242562560 (1185.0MB)
   OldSize                  = 156762112 (149.5MB)
   NewRatio                 = 2
   SurvivorRatio            = 8
   MetaspaceSize            = 21807104 (20.796875MB)
   CompressedClassSpaceSize = 1073741824 (1024.0MB)
   MaxMetaspaceSize         = 17592186044415 MB
   G1HeapRegionSize         = 0 (0.0MB)

Heap Usage:
PS Young Generation
Eden Space:
   capacity = 157810688 (150.5MB)
   used     = 21083640 (20.10692596435547MB)
   free     = 136727048 (130.39307403564453MB)
   13.360083697246159% used
From Space:
   capacity = 5242880 (5.0MB)
   used     = 0 (0.0MB)
   free     = 5242880 (5.0MB)
   0.0% used
To Space:
   capacity = 13107200 (12.5MB)
   used     = 0 (0.0MB)
   free     = 13107200 (12.5MB)
   0.0% used
PS Old Generation
   capacity = 114294784 (109.0MB)
   used     = 18184528 (17.342117309570312MB)
   free     = 96110256 (91.65788269042969MB)
   15.910199366578269% used

16895 interned Strings occupying 1655896 bytes.
  • jmap -finalizerinfo pid : 打印等待回收的对象信息
Attaching to process ID 11304, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.271-b09
Number of objects pending for finalization: 0
  • jmap -histo:live pid : 打印堆的对象统计,包括对象数、内存大小等。这个命令执行,JVM会先触发gc,然后再统计信息
# 查看所有对象,包括活跃以及非活跃的
jmap ‐histo <pid> | more

# 查看活跃对象
jmap ‐histo:live <pid> | more

 num     #instances         #bytes  class name
----------------------------------------------
   1:         41238        4229144  [C
   2:         41015         984360  java.lang.String
   3:         11133         979704  java.lang.reflect.Method
   4:          8415         931672  java.lang.Class
   5:          9280         599072  [Ljava.lang.Object;
   6:         17904         572928  java.util.concurrent.ConcurrentHashMap$Node
   7:         11700         468000  java.util.LinkedHashMap$Entry
   8:          4428         436768  [I
   9:          5437         403432  [Ljava.util.HashMap$Node;
  10:          1929         365776  [B
  11:          5924         331744  java.util.LinkedHashMap
  12:         13707         304496  [Ljava.lang.Class;
  13:          3815         274680  java.lang.reflect.Field

3379:             1             16  sun.rmi.transport.DGCImpl_Skel
3380:             1             16  sun.rmi.transport.DGCImpl_Stub
3381:             1             16  sun.rmi.transport.proxy.RMIDirectSocketFactory
3382:             1             16  sun.rmi.transport.tcp.TCPTransport$1
3383:             1             16  sun.security.provider.NativeSeedGenerator
3384:             1             16  sun.util.calendar.Gregorian
3385:             1             16  sun.util.locale.provider.AuxLocaleProviderAdapter$NullProvider
3386:             1             16  sun.util.locale.provider.CalendarDataUtility$CalendarWeekParameterGetter
3387:             1             16  sun.util.locale.provider.SPILocaleProviderAdapter
3388:             1             16  sun.util.locale.provider.TimeZoneNameUtility$TimeZoneNameGetter
3389:             1             16  sun.util.resources.LocaleData
3390:             1             16  sun.util.resources.LocaleData$LocaleDataResourceBundleControl
Total        303249       15256016
  • jmap -clstats pid : 打印Java类加载器的智能统计信息,对于每个类加载器而言,对于每个类加载器而言,它的名称,活跃度,地址,父类加载器,它所加载的类的数量和大小都会被打印。此外,包含的字符串数量和大小也会被打印
Attaching to process ID 11304, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.271-b09
finding class loader instances ..done.
computing per loader stat ..done.
please wait.. computing liveness.liveness analysis may be inaccurate ...
class_loader    classes bytes   parent_loader   alive?  type

<bootstrap>     2414    4203574   null          live    <internal>
0x00000006e1c34ac0      1       1472      null          dead    sun/reflect/DelegatingClassLoader@0x00000007c000a0a0
0x00000006e1c37ac0      1       1471      null          dead    sun/reflect/DelegatingClassLoader@0x00000007c000a0a0
0x00000006e1c3a7c0      1       1472    0x00000006e1c0de70      dead    sun/reflect/DelegatingClassLoader@0x00000007c000a0a0
0x00000006e2541950      1       880     0x00000006e1c0de70      dead    sun/reflect/DelegatingClassLoader@0x00000007c000a0a0
0x00000006e1c381c8      1       1471      null          dead    sun/reflect/DelegatingClassLoader@0x00000007c000a0a0
0x00000006e24b1840      1       1474    0x00000006e1c0de70      dead    sun/reflect/DelegatingClassLoader@0x00000007c000a0a0
0x00000006e24b4590      1       881       null          dead    sun/reflect/DelegatingClassLoader@0x00000007c000a0a0
0x00000006e24aeca0      1       1472    0x00000006e1c0de70      dead    sun/reflect/DelegatingClassLoader@0x00000007c000a0a0
0x00000006e24af7a0      1       1472    0x00000006e1c0de70      dead    sun/reflect/DelegatingClassLoader@0x00000007c000a0a0
0x00000006e2966078      1       1474    0x00000006e1c0de70      dead    sun/reflect/DelegatingClassLoader@0x00000007c000a0a0
0x00000006e1c34930      1       880     0x00000006e1c0de70      dead    sun/reflect/DelegatingClassLoader@0x00000007c000a0a0
0x00000006e1c37930      1       1471      null          dead    sun/reflect/DelegatingClassLoader@0x00000007c000a0a0
0x00000006e25414a0      1       1471    0x00000006e1c0de70      dead    sun/reflect/DelegatingClassLoader@0x00000007c000a0a0
0x00000006e1c38038      1       1471      null          dead    sun/reflect/DelegatingClassLoader@0x00000007c000a0a0
0x00000006e2964768      1       1471    0x00000006e1c0de70      dead    sun/reflect/DelegatingClassLoader@0x00000007c000a0a0

total = 120     7243    11663417            N/A         alive=1, dead=119           N/A
  • jmap -F -histo pid : -F 强制模式。 如果指定的pid 没有响应,请使用jmap -dump或jmap -histo选项。此模式不支持live子选项。
Attaching to process ID 11304, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.271-b09
Iterating over heap. This may take a while...
Object Histogram:

num       #instances    #bytes  Class description
--------------------------------------------------------------------------
1:              56745   6587240 char[]
2:              47710   1145040 java.lang.String
3:              11275   992200  java.lang.reflect.Method
4:              8415    931672  java.lang.Class
5:              4671    845760  byte[]
6:              10688   684536  java.lang.Object[]
7:              17904   572928  java.util.concurrent.ConcurrentHashMap$Node
8:              5644    509016  int[]
9:              11882   475280  java.util.LinkedHashMap$Entry
10:             5766    436488  java.util.HashMap$Node[]
11:             6052    338912  java.util.LinkedHashMap

JHAT

	将jvm的内存dump到文件中后,由于dump文件是一个二进制的文件,不方便查看,可以使用jhat工具进行查看
  • jhat ‐port <port> <file>
[root@administrator ~]# jhat -port 8083 /root/dump.hprof 
Reading from /root/dump.hprof...
Dump file created Thu Oct 13 22:11:40 CST 2022
Snapshot read, resolving...
Resolving 250364 objects...
Chasing references, expect 50 dots..................................................
Eliminating duplicate references..................................................
Snapshot resolved.
Started HTTP server on port 8083
Server is ready.

MAT

	MAT(Memory Analyzer Tool),一个基于Eclipse的内存分析工具,是一个快速、功能丰富的JAVA heap分析工具,它可以帮助我们查找内存泄漏和减少内存消耗。使用内存分析工具从众多的对象中进行分析,快速的计算出在内存中对象的占用大小,看看是谁阻止了垃圾收集器的回收工作,并可以通过报表直观的查看到可能造成这种结果的对象
  • 访问官网:https://www.eclipse.org/mat/,下载MAT工具,并进行解压,双击MemoryAnalyzer.exe启动
  • 在菜单栏,选择File -> Open File处选择dump.hprof 文件打开,进入如下页面,默认选择,点击Finish
  • 分析结果如下
  • 需注意Histogram、Dominator Tree参数
    Histogram:列出内存中的对象,对象的个数以及大小
    
    Dominator Tree:列出最大的对象以及其依赖存活的对象
    
    

JSTACK

	jstack是jdk自带的线程堆栈分析工具,使用该命令可以查看或导出Java应用程序中线程堆栈信息。
	主要作用是将正在运行的jvm的线程情况进行快照,并且打印出来
  • jstack <pId>
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.311-b11 mixed mode):

"arthas-command-execute" #54 daemon prio=5 os_prio=0 tid=0x00007f4f480a6800 nid=0xca61 waiting on condition [0x00007f4f70843000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000c8585a18> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1081)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)

"arthas-NettyHttpTelnetBootstrap-3-2" #53 daemon prio=5 os_prio=0 tid=0x00007f4f88796800 nid=0xb84d runnable [0x00007f4f70641000]
   java.lang.Thread.State: RUNNABLE
        at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
        at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269)
        at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:93)
        at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
        - locked <0x00000000c85cbed8> (a com.alibaba.arthas.deps.io.netty.channel.nio.SelectedSelectionKeySet)
        - locked <0x00000000c85cbec8> (a java.util.Collections$UnmodifiableSet)
        - locked <0x00000000c85cbe80> (a sun.nio.ch.EPollSelectorImpl)
        at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
        at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:101)
        at com.alibaba.arthas.deps.io.netty.channel.nio.SelectedSelectionKeySetSelector.select(SelectedSelectionKeySetSelector.java:68)
        at com.alibaba.arthas.deps.io.netty.channel.nio.NioEventLoop.select(NioEventLoop.java:813)
        at com.alibaba.arthas.deps.io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:460)
        at com.alibaba.arthas.deps.io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:995)
        at com.alibaba.arthas.deps.io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
        at com.alibaba.arthas.deps.io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
        at java.lang.Thread.run(Thread.java:748)

"arthas-UserStat" #51 daemon prio=9 os_prio=0 tid=0x00007f4f60527800 nid=0xb83f waiting on condition [0x00007f4f5818a000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000c85cc408> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)

"arthas-session-manager" #50 daemon prio=9 os_prio=0 tid=0x00007f4f60520000 nid=0xb83c waiting on condition [0x00007f4f5828b000]
   java.lang.Thread.State: TIMED_WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000c85ea4a8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)

  • 生产环境下的定位与分析
    • 内存溢出
    main 代码
      public static void main(String[] args) {
        ArrayList<String> arrayList = new ArrayList<>();
        while (true) {
            arrayList.add(UUID.randomUUID().toString());
        }
    }
    
    jvm 配置
    -Xms10m -Xmx10m -XX:+HeapDumpOnOutOfMemoryError
    
    将会生成一个java_pid**.hprof类似文件
    java.lang.OutOfMemoryError: GC overhead limit exceeded
    Dumping heap to java_pid16952.hprof ...
    Heap dump file created [10500212 bytes in 0.026 secs]
    Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
    	at java.lang.String.substring(String.java:1933)
    	at java.util.UUID.digits(UUID.java:386)
    	at java.util.UUID.toString(UUID.java:379)
    	at com.example.demo.job.Test.main(Test.java:10)
    
    • 死锁问题
    死锁代码
    public class TestDeadLock {
        private static Object lock1 = new Object();
        private static Object lock2 = new Object();
    
        public static void main(String[] args) {
            new Thread(() -> {
                synchronized (lock1) {
                    System.out.println("Thread1成功获取lock1锁");
                    try {
                        // 停顿2秒,让Thread2线程拿到lock2的锁
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    synchronized (lock2) {
                        System.out.println("Thread1成功获取lock2锁");
                    }
                }
            }).start();
    
            new Thread(() -> {
                synchronized (lock2) {
                    System.out.println("Thread2成功获取lock2锁");
                    try {
                        // 停顿2秒,让Thread1线程拿到lock1的锁
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    synchronized (lock1) {
                        System.out.println("Thread2成功获取lock1锁");
                    }
                }
            }).start();
        }
    }
    
    使用jstack进行分析
    D:\>jps
    12112
    18736 TestDeadLock
    7584 RemoteMavenServer36
    16116 Launcher
    17784 jar
    20088
    21448 Jps
    
    D:\>jstack 18736
    Java stack information for the threads listed above:
    ===================================================
    "Thread-1":
            at com.example.demo.excel.TestDeadLock.lambda$main$1(TestDeadLock.java:33)
            - waiting to lock <0x0000000776245d98> (a java.lang.Object)
            - locked <0x0000000776245da8> (a java.lang.Object)
            at com.example.demo.excel.TestDeadLock$$Lambda$2/1967205423.run(Unknown Source)
            at java.lang.Thread.run(Thread.java:748)
    "Thread-0":
            at com.example.demo.excel.TestDeadLock.lambda$main$0(TestDeadLock.java:18)
            - waiting to lock <0x0000000776245da8> (a java.lang.Object)
            - locked <0x0000000776245d98> (a java.lang.Object)
            at com.example.demo.excel.TestDeadLock$$Lambda$1/1911006827.run(Unknown Source)
            at java.lang.Thread.run(Thread.java:748)
    
    Found 1 deadlock.
    

可视化GC日志分析工具

  • GC日志
‐XX:+PrintGC 输出GC日志

‐XX:+PrintGCDetails 输出GC的详细日志

‐XX:+PrintGCTimeStamps 输出GC的时间戳

‐XX:+PrintGCDateStamps 输出GC的时间戳

‐XX:+PrintHeapAtGC 在进行GC的前后打印出堆的信息

‐Xloggc:./gc.log 日志文件的输出路径
  • GC日志分析
    GC Easy是一个在线的可视化、功能强大、使用简单的工具。
    • 官网 https://gceasy.io
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值