学习笔记JVM篇(五)

JVM常用命令参数

1、JPS

JPS全称 Java Process Status Tool,这个命令与Liunx的PS很像,下面我们测试一下这个命令,首先编写一段非常简单的Java代码。

JPS的语法 JPS [options] [hostid]

options:选项

-q: 只显示进程 ID (PID),不显示类名或其他信息。

-l: 显示主类和启动 JAR 文件的完整名称。

-m: 显示传递给 main 方法的参数。

-v: 显示 JVM 启动时的 classpath。

-D: 指定一个系统属性。

-help: 显示帮助信息。

plain 复制代码
public class JVMTest {

    public static void main(String[] args) {
        while (true){
            //do nothing
        }
    }
}

使用JPS命令,可以看到我们刚才启动的Java进程,同时进程号为7484

2、JInfo

Jinfo全称:Configuration info of java,java配置信息,可以查看JVM参数和动态的修改部分JVM参数

格式 jinfo [options]

-flag : 查看或设置指定的 JVM 标志。

-sysprops: 显示系统属性。

-flags: 显示 JVM 启动时的所有标志。

-help: 显示帮助信息。

示例:以刚才德尔JVMTest为例,输入命令 jinfo 7484,如下图会打印JVM的相关参数

前面说了,jinfo可以修改部分JVM参数,那么如何查看哪些参数是可以被修改的呢?这里可以使用以下命令

java -XX:+PrintFlagsFinal -version | grep manageable

3、Jstat

jstat:全称 java vitrual Machine statistic monitoring tool,是一个查看Java进程状态的工具,语法格式:

jstat {option} [interval] [vmid] [sleeptime]

参数说明

{option}: 指定要收集的信息类型。

interval\]: 采样间隔时间(毫秒),默认为 0(即只收集一次信息)。 \[vmid\]: Java 虚拟机的进程 ID。 \[sleeptime\]: 在多次采样之间暂停的时间(毫秒),仅在 interval 大于 0 时有效。 常见选项 -version: 显示版本信息。 -help: 显示帮助信息。 -gc: 显示垃圾收集统计信息。 -gccapacity: 显示各个内存区域的容量信息。 -class: 显示类加载统计信息。 -compiler: 显示即时编译器统计信息。 -print: 打印详细的统计信息。 -gcutil: 显示垃圾收集利用率信息。 -gccause: 显示导致垃圾收集的原因。 -sys: 显示系统信息。 比如我们想查看刚才的进程的GC情况,可以使用命令 jstat -gc 7484 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/01a6be0a3e224f8aa10edd50ec8efce6.png) 参数解释: S0C/S1C: Survivor 区域的容量。 S0U/S1U: Survivor 区域的使用量。 EC: Eden 区域的容量。 EU: Eden 区域的使用量。 OC: Old 区域的容量。 OU: Old 区域的使用量。 MC: Metaspace 的容量。 MU: Metaspace 的使用量。 CCSC: Compressed Class Space 的容量。 CCSU: Compressed Class Space 的使用量。 YGC: Young Generation 的垃圾收集次数。 YGCT: Young Generation 的垃圾收集总时间。 FGC: Full Garbage Collection 的次数。 FGCT: Full Garbage Collection 的总时间。 GCT: 总的垃圾收集时间。 ##### 5、jstack jstack是java栈的跟踪器,可以打印出java应用程序中所有线程的信息、包含堆栈信息、调用栈信息、锁等信息,所以常用于诊断死锁、内存泄漏等等 jstack的命令行格式如下 jstack \[-options

常用参数 -l:打印关于锁的相关信息

示例一:普通进程

还是以刚才的进程为例:jstack 7484

那么如何查看这些信息呢,我们截取一部分内容

这部分内容展示的信息如下:

内容 含义
main 当前线程名称叫main
#1 线程编号1
os_prio=0 系统中,当前线程优先级为0
cpu=2387656.25ms cpu已经执行了2387656.25ms
elapsed=2391.06s JVM 启动到现在已经过去了大约 2391 秒
tid=0x000001661696f860 nid=0x1a64 tid=0x000001661696f860 表示该线程的内部 ID。 nid=0x1a64 表示该线程的本地线程 ID(通常是操作系统分配的 ID)。
runnable runnable 表示该线程当前处于可运行状态。
[0x000000545b1ff000] [0x000000545b1ff000] 表示该线程的堆栈指针地址。
java.lang.Thread.State: RUNNABLE java.lang.Thread.State: RUNNABLE 再次确认该线程的状态为可运行状态。
at net.xdlcass.JVMTest.main(JVMTest.java:6) at net.xdlcass.JVMTest.main(JVMTest.java:6) 表示该线程当前正在执行 net.xdlcass.JVMTest 类中的 main 方法,具体在第 6 行。
Locked ownable synchronizers: - None None 表示该线程没有锁定任何同步器(如锁或监视器)。
示例二:死锁
plain 复制代码
public class DeadLock {

    private final static Object lock1 = new Object();

    private final static Object lock2 = new Object();


    public static void main(String[] args) {
        Thread thread1 = new Thread(() -> {
            synchronized (lock2){
                try {
                    System.out.println("thread1 get lock 2");
                    Thread.sleep(200L);
                    synchronized (lock1){
                        System.out.println("thread1 get lock 1");
                    }
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });


        Thread thread2 = new Thread(() -> {
            synchronized (lock1){
                try {
                    Thread.sleep(200L);
                    System.out.println("thread2 get lock 1");
                    synchronized (lock2){
                        System.out.println("thread2 get lock 2");
                        System.out.println(1111);
                    }
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        thread1.start();
        thread2.start();
    }
}
复制代码
我们使用jstack来演示
示例三:CPU过高

首先我们编写一个案例用于让CPU飙高,代码如下

plain 复制代码
public class HighCPU {

    /**
     * 提高 CPU 占用的方法。
     */
    public static void increaseCPULoad() {
        while (true) {
            // 进行一些计算操作
            int a = 1;
            for (int i = 0; i < 100000000; i++) {
                a *= 2;
                a /= 2;
            }
        }
    }

    public static void main(String[] args) {
        // 创建多个线程来提高 CPU 占用
        int numThreads = Runtime.getRuntime().availableProcessors(); // 根据处理器数量创建线程
        System.out.println("Number of available processors: " + numThreads);

        Thread[] threads = new Thread[numThreads];
        for (int i = 0; i < numThreads; i++) {
            threads[i] = new Thread(HighCPU::increaseCPULoad);
            threads[i].start();
        }
    }
}

代码解析:首先根据处理器数量来确定创建的线程数量,然后创建线程不断的死循环执行一些逻辑,这样可以让CPU寻思飙高。一般我们会用top命令来确定是哪个进程,但是现在我们知道是哪个进程所以直接省略这一步。

直接使用命令 jstack

部分内容如下:

未完待续,希望对你有所帮助。

相关推荐
智者知已应修善业1 小时前
【51单片机用数码管显示流水灯的种类是按钮控制数码管加一和流水灯】2022-6-14
c语言·经验分享·笔记·单片机·嵌入式硬件·51单片机
孞㐑¥4 小时前
Linux之Socket 编程 UDP
linux·服务器·c++·经验分享·笔记·网络协议·udp
sealaugh327 小时前
aws(学习笔记第四十八课) appsync-graphql-dynamodb
笔记·学习·aws
黄雪超7 小时前
JVM——函数式语法糖:如何使用Function、Stream来编写函数式程序?
java·开发语言·jvm
ThetaarSofVenice7 小时前
对象的finalization机制Test
java·开发语言·jvm
水木兰亭8 小时前
数据结构之——树及树的存储
数据结构·c++·学习·算法
鱼摆摆拜拜8 小时前
第 3 章:神经网络如何学习
人工智能·神经网络·学习
aha-凯心8 小时前
vben 之 axios 封装
前端·javascript·学习
freexyn9 小时前
Matlab自学笔记六十一:快速上手解方程
数据结构·笔记·matlab
很小心的小新10 小时前
12、jvm运行期优化
java·开发语言·jvm·笔记