JVM调优命令(下)

简介: JVM调优命令

七、jstack 50053 | more (必须掌握)


dbq@mac:~$ jstack 50053 | more
2021-02-27 15:32:08
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.131-b11 mixed mode):
"pool-1-thread-71" #81 prio=5 os_prio=31 tid=0x00007fbd7313c800 nid=0x1a07 waiting on condition [0x00007000081fb000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000007b9673f58> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireInterruptibly(AbstractQueuedSynchronizer.java:897)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1222)
        at java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:335)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1076)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:748)
"Attach Listener" #80 daemon prio=9 os_prio=31 tid=0x00007fbd7287d000 nid=0x6c0b waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE
"pool-1-thread-70" #79 prio=5 os_prio=31 tid=0x00007fbd7313c000 nid=0x6007 waiting on condition [0x0000700005983000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000007b9673f58> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireInterruptibly(AbstractQueuedSynchronizer.java:897)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1222)
        at java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:335)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1076)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:748)
"pool-1-thread-69" #78 prio=5 os_prio=31 tid=0x00007fbd71868800 nid=0x5807 waiting on condition [0x0000700005577000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000007b9673f58> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireInterruptibly(AbstractQueuedSynchronizer.java:897)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1222)
        at java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:335)


八、jmap


jmap -histo pid


显示对象的内存图


当我们的程序频繁GC时

Exception in thread "pool-1-thread-51" java.lang.OutOfMemoryError: GC overhead limit exceeded
[Full GC (Ergonomics)  159584K->159581K(182272K), 0.5506696 secs]
[Full GC (Ergonomics)  159584K->159581K(182272K), 0.5855513 secs]
[Full GC (Ergonomics)  159584K->159581K(182272K), 0.5552056 secs]
[Full GC (Ergonomics)  159584K->159581K(182272K), 0.5426389 secs]


可以通过这个命令查看哪些对象不被回收 (head:列出前20行)


可以多次运行该命令观察某对象是否持续增大,说明该对象不断在产生,不被回收

dbq@mac:~$ jmap -histo 52272 | head -20
         对象数              占用内存字节数
 num     #instances         #bytes  class name
----------------------------------------------
   1:        638662       20437184  java.util.concurrent.locks.AbstractQueuedSynchronizer$Node
   2:        283400       20404800  java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask
   3:        283426       11337040  java.math.BigDecimal
   4:        283400        9068800  com.mashibing.jvm.gc.TIS_FullGC_Problem01$CardInfo
   5:        283400        6801600  java.util.Date
   6:        283400        6801600  java.util.concurrent.Executors$RunnableAdapter
   7:        283400        4534400  com.mashibing.jvm.gc.TIS_FullGC_Problem01$$Lambda$2/1826771953
   8:          4726        3946808  [I
   9:             2        2662728  [Ljava.util.concurrent.RunnableScheduledFuture;
  10:          7312        1308256  [Ljava.lang.Object;
  11:          1901         152072  [C
  12:           747          85552  java.lang.Class
  13:          1889          45336  java.lang.String
  14:            42          26080  [B
  15:           929          22296  java.util.ArrayList
  16:            57          21432  java.lang.Thread
  17:           185          13320  java.lang.reflect.Field


jmap还可以把整个对导出到文件,可以离线分析


format=b标识导出格式为二进制


jmap -dump:format=b,file=/User/dbq/Documents/20201108.hprof 52272


image.png

jvisualvm离线分析堆内存


线上一般不容许jmap或者远程连接,所以需要在java启动时加上-XX:+HeapDumpOnOutOfMemoryError参数


TCPCopy:网易出的一款软件,可以将线上生产环境的tcp拷贝一份到本地,一般用于线上流量压测本地环境


九、Arthas 开源 Java 诊断工具(阿里出的)


启动并将arthas挂载到我们的程序上

dbq@mac:~/Documents/tools/jvm性能诊断工具/arthas/arthas-packaging-3.1.1$ sh as.sh
Arthas script version: 3.1.1
[INFO] JAVA_HOME: /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home
Found existing java process, please choose one and hit RETURN.
* [1]: 52193 org.jetbrains.jps.cmdline.Launcher
  [2]: 56573 com.mashibing.jvm.gc.TIS_FullGC_Problem01
  [3]: 52142
2
Arthas home: /Users/dbq/Documents/tools/jvm性能诊断工具/arthas/arthas-packaging-3.1.1
Calculating attach execution time...
Attaching to 56573 using version /Users/dbq/Documents/tools/jvm性能诊断工具/arthas/arthas-packaging-3.1.1...
real    0m1.138s
user    0m0.375s
sys 0m0.052s
Attach success.
telnet connecting to arthas server... current timestamp is 1614413542
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
  ,---.  ,------. ,--------.,--.  ,--.  ,---.   ,---.
 /  O  \ |  .--. ''--.  .--'|  '--'  | /  O  \ '   .-'
|  .-.  ||  '--'.'   |  |   |  .--.  ||  .-.  |`.  `-.
|  | |  ||  |\  \    |  |   |  |  |  ||  | |  |.-'    |
`--' `--'`--' '--'   `--'   `--'  `--'`--' `--'`-----'
wiki      https://alibaba.github.io/arthas
tutorials https://alibaba.github.io/arthas/arthas-tutorials
version   3.1.1
pid       56573
time      2021-02-27 16:12:22
$


dashboard命令:仪表盘,可以显示线程的情况


为了便于观察,我设置了线程名称


image.png

: $ thread 类似jstack


thread 线程号,可以把该线程的详细信息打出来

"GCTest-Thead" Id=1 TIMED_WAITING
    at java.lang.Thread.sleep(Native Method)
    at com.mashibing.jvm.gc.TIS_FullGC_Problem01.main(TIS_FullGC_Problem01.java:35)
Affect(row-cnt:0) cost in 16 ms.
$


thread -b: 可以查看是否有死锁

$ thread -b
No most blocking thread found!
Affect(row-cnt:0) cost in 18 ms.
$


附录一(马士兵视频中的一些问题)


解决过哪些实际调优经验?


OOM


什么情形下会发生OOM?


相关文章
|
1月前
|
存储 监控 算法
jvm-性能调优(二)
jvm-性能调优(二)
|
3天前
|
监控 架构师 Java
JVM进阶调优系列(6)一文详解JVM参数与大厂实战调优模板推荐
本文详述了JVM参数的分类及使用方法,包括标准参数、非标准参数和不稳定参数的定义及其应用场景。特别介绍了JVM调优中的关键参数,如堆内存、垃圾回收器和GC日志等配置,并提供了大厂生产环境中常用的调优模板,帮助开发者优化Java应用程序的性能。
|
8天前
|
Arthas 监控 Java
JVM知识体系学习七:了解JVM常用命令行参数、GC日志详解、调优三大方面(JVM规划和预调优、优化JVM环境、JVM运行出现的各种问题)、Arthas
这篇文章全面介绍了JVM的命令行参数、GC日志分析以及性能调优的各个方面,包括监控工具使用和实际案例分析。
25 3
|
11天前
|
Java API 对象存储
JVM进阶调优系列(2)字节面试:JVM内存区域怎么划分,分别有什么用?
本文详细解析了JVM类加载过程的关键步骤,包括加载验证、准备、解析和初始化等阶段,并介绍了元数据区、程序计数器、虚拟机栈、堆内存及本地方法栈的作用。通过本文,读者可以深入了解JVM的工作原理,理解类加载器的类型及其机制,并掌握类加载过程中各阶段的具体操作。
|
9天前
|
算法 Java
JVM进阶调优系列(4)年轻代和老年代采用什么GC算法回收?
本文详细介绍了JVM中的GC算法,包括年轻代的复制算法和老年代的标记-整理算法。复制算法适用于年轻代,因其高效且能避免内存碎片;标记-整理算法则用于老年代,虽然效率较低,但能有效解决内存碎片问题。文章还解释了这两种算法的具体过程及其优缺点,并简要提及了其他GC算法。
 JVM进阶调优系列(4)年轻代和老年代采用什么GC算法回收?
|
5天前
|
Java
JVM进阶调优系列(5)CMS回收器通俗演义一文讲透FullGC
本文介绍了JVM中CMS垃圾回收器对Full GC的优化,包括Stop the world的影响、Full GC触发条件、GC过程的四个阶段(初始标记、并发标记、重新标记、并发清理)及并发清理期间的Concurrent mode failure处理,并简述了GC roots的概念及其在GC中的作用。
|
10天前
|
算法 Java
JVM进阶调优系列(3)堆内存的对象什么时候被回收?
堆对象的生命周期是咋样的?什么时候被回收,回收前又如何流转?具体又是被如何回收?今天重点讲对象GC,看完这篇就全都明白了。
|
1月前
|
Kubernetes Java 编译器
解锁极致性能:Quarkus如何让JVM应用调优变得前所未有的简单与高效!
Quarkus是一款专为GraalVM和OpenJDK设计的Kubernetes Native Java框架,采用AOT编译技术将Java应用转化为本地代码,大幅提升启动速度与运行效率。它简化了性能调优流程,如自动优化垃圾回收、类加载、内存管理及线程管理等,使开发者无需深入理解JVM细节即可轻松提升应用性能。与传统JVM应用相比,Quarkus显著降低了性能调优的复杂度。
78 2
|
17天前
|
前端开发 Java 应用服务中间件
JVM进阶调优系列(1)类加载器原理一文讲透
本文详细介绍了JVM类加载机制。首先解释了类加载器的概念及其工作原理,接着阐述了四种类型的类加载器:启动类加载器、扩展类加载器、应用类加载器及用户自定义类加载器。文中重点讲解了双亲委派机制,包括其优点和缺点,并探讨了打破这一机制的方法。最后,通过Tomcat的实际应用示例,展示了如何通过自定义类加载器打破双亲委派机制,实现应用间的隔离。
|
2月前
|
Arthas Prometheus 监控
使用JDK自带工具调优JVM的常用命令
使用JDK自带工具调优JVM的常用命令