JVM 性能调优 -- JVM常用调优工具【jps、jstack、jmap、jstats 命令】
前言:
前面我们分析怎么去预估系统资源,怎么去设置 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.8VM 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: RUNNABLEat 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-b08using 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:2NewRatio = 2//Eden 区域和 Survivor 区域的比值 8:1:1SurvivorRatio = 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 Generationcapacity = 716177408 (683.0MB)used = 500095856 (476.92857360839844MB)free = 216081552 (206.07142639160156MB)69.82848808322086% used67973 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 FailedMethod35011 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 调优,关于可视化工具的部分我们下一篇再来分享,希望可以帮助到有需要的朋友们。
相关文章:
JVM 性能调优 -- JVM常用调优工具【jps、jstack、jmap、jstats 命令】
前言: 前面我们分析怎么去预估系统资源,怎么去设置 JVM 参数以及怎么去看 GC 日志,本篇我们分享一些常用的 JVM 调优工具,我们在进行 JVM 调优的时候,通常需要借助一些工具来对系统的进行相关分析,从而确定…...
PostgreSQL 三种关库模式
PostgreSQL 三种关库模式 基础信息 OS版本:Red Hat Enterprise Linux Server release 7.9 (Maipo) DB版本:16.2 pg软件目录:/home/pg16/soft pg数据目录:/home/pg16/data 端口:5777PostgreSQL 提供了三种关库模式&…...
《运放秘籍》第二部:仪表放大器专项知识点总结
一、差分放大器与仪表放大器的讨论 1.1. 仪放的前世今生——差分放大器原理? 1.2. 差分放大的原理 1.3. 差分放大器检测电流 1.4. 差分放大器端一:输入阻抗 1.5. 差分放大器端二:共模抑制比 1.6. 为什么关注输入阻抗?共模抑…...
C++STL之vector(超详细)
CSTL之vector 1.vector基本介绍2.vector重要接口2.1.构造函数2.2.迭代器2.3.空间2.3.1.resize2.3.2.capacity 2.4.增删查找 3.迭代器失效4.迭代器分类 🌟🌟hello,各位读者大大们你们好呀🌟🌟 🚀Ὠ…...
ubuntu环境下安装electron环境,并快速打包
1.配置镜像源 关闭防火墙,命令:sudo ufw disable 1.1配置国内镜像源: vim /etc/apt/source.list deb https://mirrors.aliyun.com/ubuntu/ jammy main restricted universe multiversedeb-src https://mirrors.aliyun.com/ubuntu/ jammy main…...
【Pytorch】优化器(Optimizer)模块‘torch.optim’
torch.optim 是 PyTorch 中提供的优化器(Optimizer)模块,用于优化神经网络模型的参数,更新网络权重,使得模型在训练过程中最小化损失函数。它提供了多种常见的优化算法,如 梯度下降法(SGD&#…...
API平台建设之路:从0到1的实践指南
在这个互联网蓬勃发展的时代,API已经成为连接各个系统、服务和应用的重要纽带。搭建一个优质的API平台不仅能为开发者提供便利,更能创造可观的商业价值。让我们一起探讨如何打造一个成功的API平台。 技术架构是API平台的根基。选择合适的技术栈对平台的…...
【Flink-scala】DataStream编程模型之窗口计算-触发器-驱逐器
DataStream API编程模型 1.【Flink-Scala】DataStream编程模型之数据源、数据转换、数据输出 2.【Flink-scala】DataStream编程模型之 窗口的划分-时间概念-窗口计算程序 文章目录 DataStream API编程模型前言1.触发器1.1 代码示例 2.驱逐器2.1 代码示例 总结 前言 本小节我想…...
信号灯集以及 P V 操作
一、信号灯集 1.1 信号灯集的概念 信号灯集是进程间同步的一种方式。 信号灯集创建后,在信号灯集内部会有很多个信号灯。 每个信号灯都可以理解为是一个信号量。 信号灯的编号是从0开始的。 比如A进程监视0号灯,B进程监视1号灯。 0号灯有资源&…...
在 Flutter app 中,通过视频 URL 下载视频到手机相册
在 Flutter app 中,通过视频 URL 下载视频到手机相册可以通过以下步骤实现: 1. 添加依赖 使用 dio 下载文件,结合 path_provider 获取临时存储路径,以及 gallery_saver 将文件保存到相册。 在 pubspec.yaml 中添加以下依赖&…...
Nature Methods | 人工智能在生物与医学研究中的应用
Nature Methods | 人工智能在生物与医学研究中的应用 生物研究中的深度学习 随着人工智能(AI)技术的迅速发展,尤其是深度学习和大规模预训练模型的出现,AI在生物学研究中的应用正在经历一场革命。从基因组学、单细胞组学到癌症生…...
Axure PR 9 随机函数 设计交互
大家好,我是大明同学。 这期内容,我们将深入探讨Axure中随机函数的用法。 随机函数 创建随机函数所需的元件 1.打开一个新的 RP 文件并在画布上打开 Page 1。 2.在元件库中拖出一个矩形元件。 3.选中矩形元件,样式窗格中,将…...
【人工智能基础05】决策树模型
文章目录 一. 基础内容1. 决策树基本原理1.1. 定义1.2. 表示成条件概率 2. 决策树的训练算法2.1. 划分选择的算法信息增益(ID3 算法)信息增益比(C4.5 算法)基尼指数(CART 算法)举例说明:计算各个…...
【人工智能基础03】机器学习(练习题)
文章目录 课本习题监督学习的例子过拟合和欠拟合常见损失函数,判断一个损失函数的好坏无监督分类:kmeans无监督分类,Kmeans 三分类问题变换距离函数选择不同的起始点 重点回顾1. 监督学习、半监督学习和无监督学习的定义2. 判断学习场景3. 监…...
HarmonyOS(60)性能优化之状态管理最佳实践
状态管理最佳实践 1、避免在循环中访问状态变量1.1 反例1.2 正例 2、避免不必要的状态变量的使用3、建议使用临时变量替换状态变量3.1 反例3.2 正例 4、参考资料 1、避免在循环中访问状态变量 在应用开发中,应避免在循环逻辑中频繁读取状态变量,而是应该…...
数据库课程设计报告 超市会员管理系统
一、系统简介 1.1设计背景 受到科学技术的推动,全球计算机的软硬件技术迅速发展,以计算机为基础支撑的信息化如今已成为现代企业的一个重要标志与衡量企业综合实力的重要标准,并且正在悄无声息的影响与改变着国内外广泛的中小型企业的运营模…...
C++算法练习-day54——39.组合总和
题目来源:. - 力扣(LeetCode) 题目思路分析 题目:给定一个整数数组 candidates 和一个目标数 target,找出所有独特的组合,这些组合中的数字之和等于 target。每个数字在每个组合中只能使用一次。 思路&a…...
计算机毕业设计PySpark+Hadoop中国城市交通分析与预测 Python交通预测 Python交通可视化 客流量预测 交通大数据 机器学习 深度学习
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
Linux的文件系统
这里写目录标题 一.文件系统的基本组成索引节点目录项文件数据的存储扇区三个存储区域 二.虚拟文件系统文件系统分类进程文件表读写过程 三.文件的存储连续空间存放方式缺点 非连续空间存放方式链表方式隐式链表缺点显示链接 索引数据库缺陷索引的方式优点:多级索引…...
【Vue3】从零开始创建一个VUE项目
【Vue3】从零开始创建一个VUE项目 手动创建VUE项目附录 package.json文件报错处理: Failed to get response from https://registry.npmjs.org/vue-cli-version-marker 相关链接: 【VUE3】【Naive UI】<NCard> 标签 【VUE3】【Naive UI】&…...
9)语法分析:半倒装和全倒装
在英语中,倒装是一种特殊的句子结构,其中主语和谓语(或助动词)的位置被颠倒。倒装分为部分倒装和全倒装两种类型,它们的主要区别在于倒装的程度和使用的场合。 1. 部分倒装 (Partial Inversion) 部分倒装是指将助动词…...
Scala关于成绩的常规操作
score.txt中的数据: 姓名,语文,数学,英语 张伟,87,92,88 李娜,90,85,95 王强,78,90,82 赵敏,92,8…...
使用Java实现度分秒坐标转十进制度的实践
目录 前言 一、度分秒的使用场景 1、表示方法 2、两者的转换方法 3、区别及使用场景 二、Java代码转换的实现 1、确定计算值的符号 2、数值的清洗 3、度分秒转换 4、转换实例 三、总结 前言 在地理信息系统(GIS)、导航、测绘等领域,…...
根据后台数据结构,构建搜索目录树
效果图: 数据源 const data [{"categoryidf": "761525000288210944","categoryids": "766314364226637824","menunamef": "经济运行","menunames": "经济运行总览","tempn…...
食品计算—FoodSAM: Any Food Segmentation
🌟🌟 欢迎来到我的技术小筑,一个专为技术探索者打造的交流空间。在这里,我们不仅分享代码的智慧,还探讨技术的深度与广度。无论您是资深开发者还是技术新手,这里都有一片属于您的天空。让我们在知识的海洋中…...
2411rust,1.83
原文 1.83.0稳定版 新的常能力 此版本包括几个说明在常环境中运行代码可干的活的大型扩展.这是指编译器在编译时必须计算的所有代码:常和静项的初值,数组长度,枚举判定值,常模板参数及可从(constfn)此类环境调用的函数. 引用静.当前,除了静项的初化器式外,禁止常环境引用静…...
tomcat加载三方包顺序
共享库 tomcat支持多个webapp共享一个三方库,而不需要每个webapp都引入该三方库 tomcat加载类顺序 bootstrap:加载jvm提供的类system:加载$CATALINA_HOME/bin下的bootstrap.jar,commons-daemon.jar,tomcat-juli.jar三个包//加载$CLASSPATH…...
计算机的错误计算(一百七十一)
摘要 探讨 MATLAB 中秦九韶(Horner)多项式的错误计算。 例1. 用秦九韶(Horner)算法计算(一百零七)例1中多项式 直接贴图吧: 这样,MATLAB 给出的仍然是错误结果,因为准…...
js对于json的序列化、反序列化有哪几种方法
在JavaScript中,对JSON(JavaScript Object Notation)进行序列化(将对象转换为JSON字符串)和反序列化(将JSON字符串转换为对象)是常见的操作。以下是一些常用的方法: 序列化…...
Linux——基础命令(2) 文件内容操作
目录 编辑 文件内容操作 1.Vim (1)移动光标 (2)复制 (3)剪切 (4)删除 (5)粘贴 (6)替换,撤销,查找 (7ÿ…...
网站方案制作/网站建设需要啥
原文:借助Canvas黑魔法,实现营销增益模型Uplift Model | 人人都是产品经理 在后互联网时代,随着营销成本的高涨,如何从存量人群中精准找到营销敏感人群进行触达,进而提高ROI一直是业务中重要的课题。 这样的业务场景…...
珠海哪家做企业网站公司好/咖啡seo是什么意思
航空订票系统系统(SSHMYSQLHTML5)(毕业论文近10000字, 包含程序代码,MySql数据库,数据库脚本) 【项目包含】【项目功能】【源码下载】本系统登录的角色有二种:会员、管理员、普通用户。管理员是能够管理会员信息、航班信息的管理、订单信息的管理、留言板的管理。会…...
网站服务器免费申请/seo优化在哪里学
首先点击IDEA左上角File Setting-->Editor-->Color Scheme -->Language Defaults Comments目录下有以下三项,分别对应三种注释 Block comment 多行注释 ———————— /* */Line comment 单行注释 —————————//Doc Comment 文档文件———…...
wordpress连接丢失/seo关键词优化的技巧
这里写目录标题三种Boot模式的差异在STM32上创建一个汇编工程led汇编闪烁灯总结三种Boot模式的差异 所谓启动,一般来说就是指我们下好程序后,重启芯片时,SYSCLK的第4个上升沿,BOOT引脚的值将被锁存。用户可以通过设置BOOT1和BOOT…...
高端定制手机网站/关键路径
考真word2007手机版是提供在线备考服务的应用软件,收录了大量的考试真题可以练习,提醒丰富全面,难度不一,层层递进,还模拟考场,支持自动阅卷、评分,提供手把手教学、答案演示等功能,…...
学美工难吗/seo 重庆
导出题库试题(101~200)共计677道试题478).在Access中,将"工资一月表","工资二月表"……中的字段"姓名"与"名单表"中的字段"姓名"建立关系,且各个月的工资表的记录都是惟一的,名单表的记录也是惟一的,…...