Solo  当前访客:1 开始使用


JVM的 jconsole

远程连接

在 JVM 的启动参数上加:
-Djava.rmi.server.hostname=localhost
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=12345
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false

hostname 是 远程目标的ip地址或者域名

port 只是一个开放的端口,别被其他应用使用就行

参数说明

内存

堆内存:内存的增长趋势、垃圾回收的频繁性和耗时情况

非堆内存:平稳性

线程

线程数:过多的线程在上下文切换时的开销

死锁:检测死锁,定位死锁

加载的类:JVM通过类加载器将类加载到内存中,类加载是在程序运行期间动态进行的,一个类只会被加载一次

卸载的类:服务关闭时,被加载到内存中的类,应该要被卸载

CPU

是Java程序在运行时,JVM进程所使用的CPU时间与总CPU时间的比例

在正常的程序运行过程中,CPU占用率可能会在不同的百分比之间波动。

如果CPU占用率持续保持在一个高位,可能的原因:频繁的IO读写操作、线程过多、死锁等。

检测死锁

使用jconsole 来查看线程的状态和活动。如果发生死锁,通常会有一些线程处于 BLOCKEDWAITING 状态,且这些状态可能持续很长时间。通过查看线程的堆栈跟踪信息,你可以尝试理解为什么线程被阻塞,并可能找到导致死锁的代码路径。

一旦你识别了死锁的原因,处理死锁通常需要你手动修改代码。这可能包括重新设计数据结构、改进同步策略、避免嵌套锁等。在某些情况下,你可能需要使用更高级的并发控制工具或技术,如 java.util.concurrent 包中的类或者锁分离等策略。

嵌套锁

当一个线程已经持有某个对象的锁时,它再次尝试获取同一个对象的锁。

Java的内建锁(即 synchronized关键字)是隐式支持重入的,即同一个线程可以多次获得同一个对象的锁而不会导致死锁

public class NestedLockingExample {  
    private final Object lock = new Object();  
  
    public void outerMethod() {  
        synchronized (lock) {  
            // 持有lock对象的锁  
            innerMethod();  
            // 释放lock对象的锁,当outerMethod方法执行完毕后  
        }  
    }  
  
    public void innerMethod() {  
        synchronized (lock) {  
            // 再次持有lock对象的锁(嵌套锁)  
            // 执行一些需要同步的操作  
        }  
    }  
  
    public static void main(String[] args) {  
        NestedLockingExample example = new NestedLockingExample();  
        example.outerMethod(); // 调用outerMethod,它会调用innerMethod,形成嵌套锁  
    }  
}
标签:
新一篇: MySql定时备份 旧一篇: 关于人的精力有限 待做的事情有限,两者之间平衡性的思考,论你为什么很累