JVM 性能调优 -- JVM常用调优工具【jps、jstack、jmap、jstats 命令】

news2024/11/30 6:30:06

前言:

前面我们分析怎么去预估系统资源,怎么去设置 JVM 参数以及怎么去看 GC 日志,本篇我们分享一些常用的 JVM 调优工具,我们在进行 JVM 调优的时候,通常需要借助一些工具来对系统的进行相关分析,从而确定当前的 JVM 是否需要进行调优,以及有哪些问题需要优化。

JVM 系列文章传送门

初识 JVM(Java 虚拟机)

深入理解 JVM(Java 虚拟机)

一文搞懂 JVM 垃圾回收(JVM GC)

深入理解 JVM 垃圾回收算法

一文搞懂 JVM 垃圾收集器

JVM 调优相关参数

JVM 场景面试题【强烈推荐】

JVM 性能调优 – 线上应用 JVM 内存的的预估设置【实战】

JVM 性能调优 – 线上应用 JVM 内存调优【实战】

JVM 性能调优 – 模拟触发 Minor GC【GC 日志分析】

JVM 性能调优 – 模拟触发 Minor GC(2)【GC 日志分析】

JVM 性能调优 – CMS 垃圾回收器 GC 日志分析【Full GC】

JVM 调优工具认识

辅助 JVM 调优的工具有很多种,从宏观上我们可以分为两类,分别是 Java 自带的相关工具和第三方辅助调优工具,本篇我们只讨论 Java 自带的 JVM 调优工具。

JVM 自带的调优工具又可以分为两类,如下:

命令行工具

  • jps:查看进程的信息。
  • jinfo:查看进程基本信息,包括启动参数、垃圾回收器等信息。
  • jstack:查看 Java 进程的线程的堆栈信息。
  • jmap:主要用于生成堆转内存快照。
  • jhat:JVM 堆转储快照分析工具,一般和 jmap 结合使用,使用 jmap 把进程内存使用情况 dump 到文件中,再用 jhat 进行分析查看。
  • jstat:JVM 统计监测工具。

可视化工具

  • jconsole:用于对 JVM 的内存、线程、类进行监控,是一个基于 JMX 的 GUI 性能监控工具。
  • jsisualvm:能够监控 CPU、内存使用情况,也可以查看程序运行时候的 GC 情况。

以上就是 Java 提供的一些常用的 JVM 调优辅助工具。

jps 命令

jps 命令主要是查看正在运行的 Java 进程信息,用法如下:

jps

执行结果如下:

14192 nacos-server.jar
27680 RemoteMavenServer36
18852
19508 Launcher
31108 Jps
12232
18280 RemoteMavenServer36
30332 Launcher
jps -l

执行结果如下:

14192 D:\meto\study\nacos\nacos-server-2.3.2\nacos\target\nacos-server.jar
27680 org.jetbrains.idea.maven.server.RemoteMavenServer36
18852
19508 org.jetbrains.jps.cmdline.Launcher
20020 sun.tools.jps.Jps
12232
18280 org.jetbrains.idea.maven.server.RemoteMavenServer36
30332 org.jetbrains.jps.cmdline.Launcher

对比 jps 和 jps -l 命令的区别就是 jps -l 可以看到完整的包路径,而 JPS 命令看不到,两个命令都可以看到进程号。

jinfo 命令

jinfo 命令需要用于实时查看正在运行的 Java 进程基本信息,包括启动参数、垃圾回收器等信息。

jinfo 命令的执行方式是:jinfo pid,执行如下:

jinfo 14192

执行结果如下:

Attaching to process ID 14192, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.121-b13
Java System Properties:

java.vendor = Oracle Corporation
sun.java.launcher = SUN_STANDARD
catalina.base = D:\meto\study\nacos\nacos-server-2.3.2\nacos\bin
sun.management.compiler = HotSpot 64-Bit Tiered Compilers
catalina.useNaming = false
nacos.local.ip = 192.168.123.132
loader.path = D:\meto\study\nacos\nacos-server-2.3.2\nacos/plugins,D:\meto\study\nacos\nacos-server-2.3.2\nacos/plugins/health,D:\meto\study\nacos\nacos-server-2.3.2\nacos/plugins/cmdb,D:\meto\study\nacos\nacos-server-2.3.2\nacos/plugins/selector
os.name = Windows 10
sun.boot.class.path = D:\tool\jdk\jdk\jre\lib\resources.jar;D:\tool\jdk\jdk\jre\lib\rt.jar;D:\tool\jdk\jdk\jre\lib\sunrsasign.jar;D:\tool\jdk\jdk\jre\lib\jsse.jar;D:\tool\jdk\jdk\jre\lib\jce.jar;D:\tool\jdk\jdk\jre\lib\charsets.jar;D:\tool\jdk\jdk\jre\lib\jfr.jar;D:\tool\jdk\jdk\jre\classes
sun.desktop = windows
java.vm.specification.vendor = Oracle Corporation
java.runtime.version = 1.8.0_121-b13
user.name = user.name
user.language = zh
sun.boot.library.path = D:\tool\jdk\jdk\jre\bin
com.zaxxer.hikari.pool_number = 1
CONSOLE_LOG_CHARSET = GBK
nacos.home = D:\meto\study\nacos\nacos-server-2.3.2\nacos
PID = 14192
java.version = 1.8.0_121
user.timezone = Asia/Shanghai
sun.arch.data.model = 64
java.endorsed.dirs = D:\tool\jdk\jdk\jre\lib\endorsed
sun.cpu.isalist = amd64
sun.jnu.encoding = GBK
file.encoding.pkg = sun.io
file.separator = \
java.specification.name = Java Platform API Specification
java.class.version = 52.0
nacos.standalone = true
user.country = CN
java.home = D:\tool\jdk\jdk\jre
java.vm.info = mixed mode
os.version = 10.0
path.separator = ;
java.vm.version = 25.121-b13
user.variant =
java.protocol.handler.pkgs = org.springframework.boot.loader
java.awt.printerjob = sun.awt.windows.WPrinterJob
sun.io.unicode.encoding = UnicodeLittle
awt.toolkit = sun.awt.windows.WToolkit
sun.stdout.encoding = ms936
user.script =
user.home = C:\Users\Administrator
java.specification.vendor = Oracle Corporation
java.library.path = D:\tool\jdk\jdk\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;C:\ProgramData\Oracle\Java\javapath;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;D:\tool\jdk\jdk\bin;D:\tool\jdk\jdk\jre\bin;D:\tool\git\Git\cmd;D:\tool\svn\bin;D:\tool\maven\apache-maven-3.8.4-bin\apache-maven-3.8.4\bin;D:\tool\web\nodejs\;C:\Users\Administrator\AppData\Local\Microsoft\WindowsApps;C:\Users\Administrator\AppData\Roaming\npm;D:\tool\web\webstorm\Microsoft VS Code\bin;D:\tool\idea202103\IntelliJ IDEA 2021.3.3\bin;;.
java.vendor.url = http://java.oracle.com/
spring.beaninfo.ignore = true
java.vm.vendor = Oracle Corporation
java.runtime.name = Java(TM) SE Runtime Environment
sun.java.command = D:\meto\study\nacos\nacos-server-2.3.2\nacos\target\nacos-server.jar --spring.config.additional-location=file:D:\meto\study\nacos\nacos-server-2.3.2\nacos/conf/ --logging.config=D:\meto\study\nacos\nacos-server-2.3.2\nacos/conf/nacos-logback.xml nacos.nacos
java.class.path = D:\meto\study\nacos\nacos-server-2.3.2\nacos\target\nacos-server.jar
nacos.function.mode = All
java.vm.specification.name = Java Virtual Machine Specification
java.vm.specification.version = 1.8
catalina.home = D:\meto\study\nacos\nacos-server-2.3.2\nacos\bin
sun.cpu.endian = little
sun.os.patch.level =
java.awt.headless = true
java.io.tmpdir = C:\Users\ADMINI~1\AppData\Local\Temp\
FILE_LOG_CHARSET = GBK
java.vendor.url.bug = http://bugreport.sun.com/bugreport/
os.arch = amd64
java.awt.graphicsenv = sun.awt.Win32GraphicsEnvironment
java.ext.dirs = D:\tool\jdk\jdk\jre\lib\ext;C:\Windows\Sun\Java\lib\ext
user.dir = D:\meto\study\nacos\nacos-server-2.3.2\nacos\bin
line.separator =

java.vm.name = Java HotSpot(TM) 64-Bit Server VM
nacos.mode = stand alone
sun.stderr.encoding = ms936
file.encoding = GBK
java.specification.version = 1.8

VM Flags:
Non-default VM flags: -XX:CICompilerCount=4 -XX:InitialHeapSize=536870912 -XX:MaxHeapSize=536870912 -XX:MaxNewSize=268435456 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=268435456 -XX:OldSize=268435456 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
Command line:  -Xms512m -Xmx512m -Xmn256m -Dnacos.standalone=true -Dloader.path=D:\meto\study\nacos\nacos-server-2.3.2\nacos/plugins,D:\meto\study\nacos\nacos-server-2.3.2\nacos/plugins/health,D:\meto\study\nacos\nacos-server-2.3.2\nacos/plugins/cmdb,D:\meto\study\nacos\nacos-server-2.3.2\nacos/plugins/selector -Dnacos.home=D:\meto\study\nacos\nacos-server-2.3.2\nacos

可以看到执行 jinfo 命令打印了非常多的信息,包括 Java 版本、环境信息、JVM 参数等非常多的信息,这些信息并不是我们都要关注的,如果我们想要少看到一些信息,可以使用 jinfo -flags 线程pid 命令。

jinfo -flags 14192

执行结果如下:

Attaching to process ID 14192, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.121-b13
Non-default VM flags: -XX:CICompilerCount=4 -XX:InitialHeapSize=536870912 -XX:MaxHeapSize=536870912 -XX:MaxNewSize=268435456 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=268435456 -XX:OldSize=268435456 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
Command line:  -Xms512m -Xmx512m -Xmn256m -Dnacos.standalone=true -Dloader.path=D:\meto\study\nacos\nacos-server-2.3.2\nacos/plugins,D:\meto\study\nacos\nacos-server-2.3.2\nacos/plugins/health,D:\meto\study\nacos\nacos-server-2.3.2\nacos/plugins/cmdb,D:\meto\study\nacos\nacos-server-2.3.2\nacos/plugins/selector -Dnacos.home=D:\meto\study\nacos\nacos-server-2.3.2\nacos

可以看到执行 jinfo -flags 命令后打印的信息少了很多,主要都是 JVM 的一些参数信息,这些信息是我们需要重点关注的信息。

jstack 命令

jstack 命令,主要用于查看 Java 进程内线程的堆栈信息,用法如下:

jstack 进程id

进程 id 就是 Java 进行的 id,执行命令如下:

jstack 114684

执行结果如下:

2024-11-20 19:51:55
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.251-b08 mixed mode):

"Keep-Alive-Timer" #13930 daemon prio=8 os_prio=0 tid=0x00007fb22c0de800 nid=0x1834c waiting on condition [0x00007fb1a9b93000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
        at sun.net.www.http.KeepAliveCache.run(KeepAliveCache.java:172)
        at java.lang.Thread.run(Thread.java:748)

"pool-3-thread-17" #10344 prio=5 os_prio=0 tid=0x00007fb2562f0000 nid=0x1068a waiting on condition [0x00007fb1ad9d1000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000dd9903f0> (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)

"org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#6-2" #10343 prio=5 os_prio=0 tid=0x00007fb1e0de2000 nid=0x1067e waiting on condition [0x00007fb1a928a000]
   java.lang.Thread.State: TIMED_WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000dd993d78> (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.LinkedBlockingQueue.poll(LinkedBlockingQueue.java:467)
        at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.nextMessage(BlockingQueueConsumer.java:499)
        at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:927)
        at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:913)
        at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$1600(SimpleMessageListenerContainer.java:81)
        at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.mainLoop(SimpleMessageListenerContainer.java:1284)
        at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1190)
        at java.lang.Thread.run(Thread.java:748)

"pool-3-thread-16" #10342 prio=5 os_prio=0 tid=0x00007fb256f9a800 nid=0x1067b waiting on condition [0x00007fb1a4f53000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000dd9903f0> (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)

"pool-3-thread-15" #10341 prio=5 os_prio=0 tid=0x00007fb256809800 nid=0x1067a waiting on condition [0x00007fb1acfc7000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000dd9903f0> (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)

"pool-3-thread-14" #10340 prio=5 os_prio=0 tid=0x00007fb256542800 nid=0x10679 waiting on condition [0x00007fb1af1e1000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000dd9903f0> (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)

"pool-3-thread-13" #10339 prio=5 os_prio=0 tid=0x00007fb22801b000 nid=0x10677 waiting on condition [0x00007fb1aded6000]
   java.lang.Thread.State: TIMED_WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000dd9963e8> (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)

"AMQP Connection 10.100.40.29:5672" #10338 prio=5 os_prio=0 tid=0x00007fb22800a000 nid=0x10676 runnable [0x00007fb1adfd7000]
   java.lang.Thread.State: RUNNABLE
        at java.net.SocketInputStream.socketRead0(Native Method)
        at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
        at java.net.SocketInputStream.read(SocketInputStream.java:171)
        at java.net.SocketInputStream.read(SocketInputStream.java:141)
        at java.io.BufferedInputStream.fill(BufferedInputStream.java:246)
        at java.io.BufferedInputStream.read(BufferedInputStream.java:265)
        - locked <0x00000000dd995db0> (a java.io.BufferedInputStream)
        at java.io.DataInputStream.readUnsignedByte(DataInputStream.java:288)
        at com.rabbitmq.client.impl.Frame.readFrom(Frame.java:91)
        at com.rabbitmq.client.impl.SocketFrameHandler.readFrame(SocketFrameHandler.java:184)
        - locked <0x00000000dd995d90> (a java.io.DataInputStream)
        at com.rabbitmq.client.impl.AMQConnection$MainLoop.run(AMQConnection.java:598)
        at java.lang.Thread.run(Thread.java:748)

"org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#4-2" #10334 prio=5 os_prio=0 tid=0x00007fb1dc02d800 nid=0x10671 waiting on condition [0x00007fb1ae0d8000]
   java.lang.Thread.State: TIMED_WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000dd991b78> (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.LinkedBlockingQueue.poll(LinkedBlockingQueue.java:467)
        at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.nextMessage(BlockingQueueConsumer.java:499)
        at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:927)
        at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:913)
        at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$1600(SimpleMessageListenerContainer.java:81)
        at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.mainLoop(SimpleMessageListenerContainer.java:1284)
        at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1190)
        at java.lang.Thread.run(Thread.java:748)

"org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#2-2" #10331 prio=5 os_prio=0 tid=0x00007fb1c8030800 nid=0x1066f waiting on condition [0x00007fb1adad2000]
   java.lang.Thread.State: TIMED_WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000dd992c88> (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.LinkedBlockingQueue.poll(LinkedBlockingQueue.java:467)
        at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.nextMessage(BlockingQueueConsumer.java:499)
        at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:927)
        at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:913)
        at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$1600(SimpleMessageListenerContainer.java:81)
        at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.mainLoop(SimpleMessageListenerContainer.java:1284)
        at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1190)
        at java.lang.Thread.run(Thread.java:748)

"org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#0-2" #10332 prio=5 os_prio=0 tid=0x00007fb1b8031000 nid=0x1066e waiting on condition [0x00007fb1af2e2000]
   java.lang.Thread.State: TIMED_WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000dd994e98> (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.LinkedBlockingQueue.poll(LinkedBlockingQueue.java:467)
        at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.nextMessage(BlockingQueueConsumer.java:499)
        at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:927)
        at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:913)
        at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$1600(SimpleMessageListenerContainer.java:81)
        at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.mainLoop(SimpleMessageListenerContainer.java:1284)
        at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1190)
        at java.lang.Thread.run(Thread.java:748)

可以看到执行 jstack 命令后,输出了线程堆栈信息,因为会输出当前进程中的所有线程堆栈信息,会非常多,这里只贴出来了一小部分。

以上就是 jstack 命令的使用方法,jstack 命令主要用于查看 Java 进程对应的线程运行情况。

jmap 命令

jmap 命令非常实用,主要用于生成堆转内存快照,方便查看内存的使用情况,用法如下:

jmap -heap  114684

执行结果如下:

Attaching to process ID 114684, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.251-b08

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

//堆配置
Heap Configuration:
   //空闲堆空间的最小百分比
   MinHeapFreeRatio         = 0
   //空闲堆空间的最大百分比
   MaxHeapFreeRatio         = 100
   //堆空间允许的最大值
   MaxHeapSize              = 1073741824 (1024.0MB)
   //新生代堆空间的默认值
   NewSize                  = 357564416 (341.0MB)
   //新生代堆空间允许的最大值
   MaxNewSize               = 357564416 (341.0MB)
   //老年代堆空间的默认值
   OldSize                  = 716177408 (683.0MB)
   //新生代与老年代的堆空间比值 新生代:老年代=1:2
   NewRatio                 = 2
   //Eden 区域和 Survivor 区域的比值 8:1:1
   SurvivorRatio            = 8
   //元空间默认值
   MetaspaceSize            = 268435456 (256.0MB)
   //压缩卷使用空间大小
   CompressedClassSpaceSize = 528482304 (504.0MB)
   //元空间允许的最大值
   MaxMetaspaceSize         = 536870912 (512.0MB)
   //使用 G1 垃圾回收器时 每个 Region 空间的大小
   G1HeapRegionSize         = 0 (0.0MB)

//JVM 堆中各个区域内存使用情况
Heap Usage:
PS Young Generation
Eden Space:
   capacity = 352321536 (336.0MB)
   used     = 34211200 (32.6263427734375MB)
   free     = 318110336 (303.3736572265625MB)
   9.710221063523065% used
From Space:
   capacity = 2621440 (2.5MB)
   used     = 1721936 (1.6421661376953125MB)
   free     = 899504 (0.8578338623046875MB)
   65.6866455078125% used
To Space:
   capacity = 2621440 (2.5MB)
   used     = 0 (0.0MB)
   free     = 2621440 (2.5MB)
   0.0% used
PS Old Generation
   capacity = 716177408 (683.0MB)
   used     = 500095856 (476.92857360839844MB)
   free     = 216081552 (206.07142639160156MB)
   69.82848808322086% used

67973 interned Strings occupying 6972816 bytes.

jmap 命令不仅可以直接查看当前堆内存情况的用法,还有一个重要的用途是用来导出 dump 文件。

使用 jmap 导出 dump 文件,用法如下:

jmap -dump:format=b,file=heap.hprof <pid>
  • format=b:表示以 hprof 二进制格式转储 Java 堆的内存。
  • file=heap.hprof: heap.hprof 是你定义的快照 dump 文件的文件名。
  • :Java 进程 id。
jmap -dump:format=b,file=heap.hprof <pid>

演示案例如下:

jmap -dump:format=b,file=/tmp/mydump.hprof 114684

执行结果如下:

Dumping heap to /tmp/mydump.hprof ...
Heap dump file created

去 tmp 目录下查询文件结果如下:
在这里插入图片描述

jmap 命令生成的 dump 文件是一个进程或系统在某一给定时间的快照,比如在进程崩溃时,我们可以通过 jmap 命令生成 dump 文件方便进行问题排查,dump 文件中包含了程序运行的线程信息、堆栈调用信息、异常信息等。

jhat 命令

jhat 命令的作用就是分析 jmap 转储的 dump 文件。

使用演示如下:

jhat mydump.hprof 

命令执行结果如下:

Reading from mydump.hprof...
Dump file created Wed Nov 20 17:25:56 CST 2024
Snapshot read, resolving...
Resolving 8852631 objects...
Chasing references, expect 1770 dots..........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
Eliminating duplicate references..........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.

命令执行完成后,我们看到了这么一句话:Started HTTP server on port 7000,也就是在本机服务器的 7000 端口上运行了一个小程序,我们可以通过 7000 端口进行访问,其实在执行 jhat 命令后,会启动一个内置的 HTTP 服务器,分析 dump 文件并将结果以HTML形式展示。

我们在浏览器访问如下:

在这里插入图片描述

jhat 命令的分享就到这里啦。

jstat 命令

jstat 是 JDK 自带的一个轻量级 JVM 调优工具,全称 “Java Virtual Machine statistics monitoring tool”,主要利用 JVM 内建的指令对 Java 应用程序的资源和性能进行实时的命令行的监控,包括了对 JVM 堆的各个空间的监控以及垃回收的相关信息统计,常用命令如下(pid 是 Java 应用进程id):

  • jstat -class pid:查看 Java 进程加载的 class 数量,以及所占空间信息。
  • jstat -compiler pid: 查看 Java 进程 JVM 实时编译信息。
  • jstat -gc pid:查看 Java 进程的 gc 相关信息。
  • jstat -gccapacity pid:查看 Java 进程内存中堆内存的大小分布。
  • jstat -gccause pid:查看 Java 进程有关垃圾收集的信息。
  • jstat -gcnew pid:查看 Java 进程中 JVM 年轻代的对象信息。
  • jstat -gcnewcapacity pid:查看 Java 进程中 JVM 年轻代的空间大小。
  • jstat -gcold pid:查看 Java 进程中 JVM 老年代的空间大小。
  • jstat -gcoldcapacity pid:查看 Java 进程中 JVM 老年代容量大小统计。
  • jstat -gcmetacapacity pid:查看 Java 进程中 JVM 元空间信息统计。
  • jstat -gcutil pid:查看 Java 进程中 JVM 垃圾收集信息统计。
  • jstat -printcompilation pid:查看 JVM 编译方法的统计。

jstat -class pid 命令演示:

jstat -class 114368

执行结果如下:

Loaded  Bytes  Unloaded  Bytes     Time   
 28132 51810.5        0     0.0      41.06

结果分析:

  • Loaded:装载的类的数量,这里是 28132 个类。
  • Bytes:装载的字节数,这里是 51810.5 字节。
  • Unloaded:卸载的类的数量,没有被卸载的类。
  • Bytes:卸载的类字节数,卸载的类的字节数。
  • Time:装载和卸载类使用的时间,这里是 41.06秒。

jstat -compiler pid 命令演示:

jstat -compiler 114368

执行结果如下:

Compiled Failed Invalid   Time   FailedType FailedMethod
   35011      1       0   133.75          1 com/alibaba/csp/sentinel/util/TimeUtil$1 run

结果分析:

  • Compiled:编译执行的任务数量,这里是 35011 个。
  • Failed:编译失败的任务数量,这里是 1个。
  • Invalid:编译任务执行失效的数量,这里 0个。
  • Time:编译任务消耗的时间,这里是 133.75秒。
  • FailedMethod:最后一个编译失败任务所在的类及方法。

jstat -gc pid 命令演示:

jstat -gc 114368

执行结果如下:

 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT   
1536.0 1536.0  0.0   368.0  346112.0 214732.0  699392.0   597598.7  169856.0 159867.7 20864.0 19147.1    297    4.072   0      0.000    4.072

结果分析:

  • S0C:Survivor From 区空间容量,单位 KB。
  • S1C:Survivor To 区空间容量,单位 KB。
  • S0U:Survivor From 区空间已经使用的容量,单位 KB。
  • S1U:Survivor To 区空间已经使用的容量,单位 KB。
  • EC:Eden 区域空间总容量,单位 KB。
  • EU:Eden 区域空间已使用总容量,单位 KB。
  • OC:Old 区域空间总容量,单位 KB。
  • OU:Old 区域空间已经使用的容量,单位 KB。
  • MC:元空间 Metaspace 空间总容量,单位 KB。
  • MU:元空间 Metaspace 空间已经使用的容量,单位 KB。
  • CCSC:压缩类空间容量,单位 KB。
  • CCSU:压缩类空间已经使用的容量,单位 KB。
  • YGC:Minor GC 回收的空间数量,单位 KB。
  • YGCT:Minor GC 回收消耗的时间,单位 秒。
  • FGC:Full GC 回收的空间数量,单位 KB。
  • FGCT:Full GC 回收消耗的时间,单位 秒。
  • GCT:总 GC 时间,单位 秒。

jstat -gcutil pid 命令演示:

jstat -gcutil pid

举例如下:

jstat -gcutil 114368

执行结果如下:

  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT   
 16.50   0.00  43.55  85.35  94.11  91.77    282    3.898     0    0.000    3.898

jstat -gcutil 命令执行结果解释如下:

  • S0:年轻代中第一个 survivor(From) 区已使用内存占当前容量百分比。
  • S1:年轻代中第二个 survivor(To)区已使用内存占当前容量百分比。
  • E:年轻代中 Eden 区已使用的内存占当前容量百分比。
  • O:老年代已使用的内存占当前容量百分比。
  • M:元数据区已使用的占当前容量百分比。
  • CCS:压缩类空间已使用的占当前容量百分比。
  • YGC :从应用程序启动到采样时年轻代中 GC 次数。
  • YGCT :从应用程序启动到采样时年轻代中 GC 所用时间,单位:秒。
  • FGC :从应用程序启动到采样时 Full GC 的次数。
  • FGCT :从应用程序启动到采样时 Full GC所用时间,单位:秒。
  • GCT:从应用程序启动到采样时 GC 用的总时间,单位:秒。

jstat 命令的使用就分享到这里,还有几个跟 GC 相关的用法大同小异,感兴趣的自己去试一下,各个字段的含义也都差不多,只是从不通过粒度上来进行了分析。

总结:本篇分享 JDK 自带的一些 JVM 调优工具的使用,使用 jps、jinfo、jmap、jstack、jhat、jstat 命令来查看 Java 应用程序的堆栈信息,来辅助我们进行 JVM 调优,关于可视化工具的部分我们下一篇再来分享,希望可以帮助到有需要的朋友们。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2250258.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

net9 abp vnext 多语言通过数据库动态管理

通过数据库加载实现动态管理&#xff0c;用户可以自己修改界面显示的文本&#xff0c;满足国际化需求 如图所示,前端使用tdesign vnext 新建表TSYS_Localization与TSYS_LocalizationDetail 国旗图标下载网址flag-icons: Free Country Flags in SVG 在Shared下创建下图3个文件 …

Vue:使用 KeepAlive 缓存切换掉的 component

一、内置特殊元素 不是组件 <component>、<slot> 和 <template> 具有类似组件的特性&#xff0c;也是模板语法的一部分。但它们并非真正的组件&#xff0c;同时在模板编译期间会被编译掉。因此&#xff0c;它们通常在模板中用小写字母书写。 1.1 <compone…

Spring中每次访问数据库都要创建SqlSession吗?

一、SqlSession是什么二、源码分析1&#xff09;mybatis获取Mapper流程2&#xff09;Spring创建Mapper接口的代理对象流程3&#xff09;MapperFactoryBean#getObject调用时机4&#xff09;SqlSessionTemplate创建流程5&#xff09;SqlSessionInterceptor拦截逻辑6&#xff09;开…

【数据结构】填空集

基本术语 顺序队列在实现的时候&#xff0c;通常将数组看成是一个首尾相连的循环队列&#xff0c;这样做的目的是为避免产生&#xff08;溢出&#xff09;现象 数组q[M]&#xff08;M等于6&#xff09;存储一个循环队&#xff0c;first和last分别指向首尾指针。已知first2,la…

【趣味升级版】斗破苍穹修炼文字游戏HTML,CSS,JS

目录 图片展示 开始游戏 手动升级&#xff08;满100%即可升级&#xff09; 升级完成&#xff0c;即可解锁打怪模式 新增功能说明&#xff1a; 如何操作&#xff1a; 完整代码 实现一个简单的斗破苍穹修炼文字游戏&#xff0c;你可以使用HTML、CSS和JavaScript结合来构建…

【在Linux世界中追寻伟大的One Piece】多线程(三)

目录 1 -> Linux线程同步 1.1 -> 条件变量 1.2 -> 同步概念与竞态条件 1.3 -> 条件变量函数 1.4 -> 为什么pthread_cond_wait需要互斥量 1.5 -> 条件变量使用规范 2 -> 生产者消费者模型 2.1 -> 为什么要使用生产者消费者模型 2.2 -> 生产…

AI数据分析工具(一)

Looker Studio&#xff08;谷歌&#xff09;-免费 优点 免费使用&#xff1a;对于中小型企业和个人用户来说&#xff0c;没有任何费用压力&#xff0c;可以免费享受到数据可视化和报表创建的功能。与Google服务集成&#xff1a;特别适合使用Google产品生态的企业&#xff0c;…

个人博客接入github issue风格的评论,utteranc,gitment

在做个人博客的时候&#xff0c;如果你需要评论功能&#xff0c;但是又不想构建用户体系和评论模块&#xff0c;那么可以直接使用github的issue提供的接口&#xff0c;对应的开源项目有utteranc和gitment&#xff0c;尤其是前者。 它们的原理是一样的&#xff1a;在博客文章下…

springboot 配置跨域访问

什么是 CORS&#xff1f; CORS&#xff0c;全称是“跨源资源共享”&#xff08;Cross-Origin Resource Sharing&#xff09;&#xff0c;是一种Web应用程序的安全机制&#xff0c;用于控制不同源的资源之间的交互。 在Web应用程序中&#xff0c;CORS定义了一种机制&#xff0…

探索Python WebSocket新境界:picows库揭秘

文章目录 探索Python WebSocket新境界&#xff1a;picows库揭秘第一部分&#xff1a;背景介绍第二部分&#xff1a;picows库概述第三部分&#xff1a;安装picows库第四部分&#xff1a;简单库函数使用方法第五部分&#xff1a;场景应用第六部分&#xff1a;常见Bug及解决方案第…

【Linux】-学习笔记06

第二章、时间同步服务器 2.1时间同步服务器的使用 2.1.1系统时区时间的管理 timedatectl set-time "2024-02-13 10:41:55" ##设定系统时间 timedatectl list-timezones ##显示系统的所有时区 timedatectl set-timezone "Asia/Shangh…

Mac使用charles抓包

一、官网下载安装 二、配置Help--->SSL Proxying 有证书选择全部信任即可 三、设置系统代理&#xff0c;mac每次重启都需要选择&#xff0c;否则会没有数据 四、设置端口&#xff08;如果无法获取https&#xff09; 五、手机链接&#xff0c;从网页下载证书保存到手机&…

3d扫描建模产品开发-三维扫描检测蓝光检测

现当下&#xff0c;汽车制造、航空航天&#xff0c;还是消费电子、医疗器械&#xff0c;三维扫描检测与蓝光技术正以前所未有的精度和效率&#xff0c;推动着产品从概念到实物的快速转化。 三维扫描技术&#xff0c;简而言之&#xff0c;就是通过激光、结构光&#xff08;如蓝…

Hive中的基本数据类型和表的类型

Hive支持关系数据库中大多数据基本数据类型&#xff0c;同时还支持三种复杂类型。 示例&#xff1a; Hive表 创建表 – 直接建表法 create table t_page_view ( page_id bigint comment ‘页面ID’, page_name string comment ‘页面名称’, page_url string comment ‘页面…

Python PDF转JPG图片小工具

Python PDF转JPG图片小工具 1.简介 将单个pdf装换成jpg格式图片 Tip: 1、软件窗口默认最前端&#xff0c;不支持调整窗口大小&#xff1b; 2、可通过按钮选择PDF文件&#xff0c;也可以直接拖拽文件到窗口&#xff1b; 3、转换质量有5个档位&#xff0c;&#xff08;0.25&a…

剖析 SpringBoot 于夕阳红公寓管理系统架构搭建的核心作用

3 系统分析 本文作者在确定了研究的课题之后&#xff0c;从各大数字图书馆下载文献来阅读&#xff0c;并了解同类型的网站具备的大致功能&#xff0c;然后与本系统用户的实际需求结合进行分析&#xff0c;得出本系统要研究的具体功能与性能。虽然分析系统这一阶段性工作主要是确…

springboot336社区物资交易互助平台pf(论文+源码)_kaic

毕 业 设 计&#xff08;论 文&#xff09; 社区物资交易互助平台设计与实现 摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff…

嵌入式linux系统中网络编程的具体实现

1.网络编程简介 要编写通过计算机网络通信的程序,首先要确定这些程序同通信的协议(protocol),在设计一个协议的细节之前,首先要分清程序是由哪个程序发起以及响应何时产生。 举例来说,一般认为WEB服务器程序是一个长时间运行的程序(守护进程deamon),它只在响应来自网…

vue3.0 根据富文本html页面生成压缩包(含视频在线地址、图片在线地址、前端截图、前端文档)

vue3.0生成压缩包&#xff08;含在线地址、前端截图、前端文档&#xff09; 需求描述效果开始下载插件包基本代码构造 点击下载按钮1.截图content元素&#xff0c;并转化为pdfcanvas putImageData、getImageDatagetImageData 获取指定矩形区域的像素信息putImageData 将这些数据…

由于导包而引发的错误

今天在调试时发现删除功能无论如何都无法实现&#xff0c;于是调试找到了mapper层的错误但不知道为什么报错。以下是报错信息。 Caused by: org.apache.ibatis.binding.BindingException: Parameter userIds not found. Available parameters are [arg0, collection, list]at o…