学习笔记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

参数解释:

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

部分内容如下:

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

相关推荐
z樾5 分钟前
C++实现用户分组--学习
开发语言·c++·学习
kuiini32 分钟前
C 语言学习-02【编程习惯】
c语言·学习
customer081 小时前
【开源免费】基于SpringBoot+Vue.JS课程答疑系统(JAVA毕业设计)
java·jvm·vue.js·spring boot·spring cloud·kafka·开源
AI大模型-王哥1 小时前
产业科普 | 什么是人工智能和大模型?大模型入门到精通 看完你就明白了
人工智能·学习·langchain·大模型·大模型学习·大模型入门·大模型教程
我叫乐多你养我啊1 小时前
Windows远程连接Docker服务
笔记·docker
无敌最俊朗@2 小时前
unity3d————协程原理讲解
开发语言·学习·unity·c#·游戏引擎
青椒大仙KI112 小时前
24/11/14 算法笔记 EM算法期望最大化算法
人工智能·笔记·算法
一叶飘零_sweeeet2 小时前
JVM 中的完整 GC 流程
java·开发语言·jvm
猫爪笔记2 小时前
JavaSE:运算符 (学习笔记)
java·开发语言·笔记·学习
2301_780853862 小时前
JVM概述
jvm