学习笔记JVM篇(五)

devtools/2024/9/22 14:19:39/

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: 显示帮助信息。

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

384)

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

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

内容含义
main当前线程名称叫main
#1线程编号1
os_prio=0系统中,当前线程优先级为0
cpu=2387656.25mscpu已经执行了2387656.25ms
elapsed=2391.06sJVM 启动到现在已经过去了大约 2391 秒
tid=0x000001661696f860 nid=0x1a64
tid=0x000001661696f860 表示该线程的内部 ID。
nid=0x1a64 表示该线程的本地线程 ID(通常是操作系统分配的 ID)。
runnablerunnable 表示该线程当前处于可运行状态。
[0x000000545b1ff000][0x000000545b1ff000] 表示该线程的堆栈指针地址。
java.lang.Thread.State: RUNNABLEjava.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 表示该线程没有锁定任何同步器(如锁或监视器)。
示例二:死锁
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飙高,代码如下

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

部分内容如下:

在这里插入图片描述

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


http://www.ppmy.cn/devtools/115494.html

相关文章

【C++】—— string模拟实现

前言&#xff1a; 学习了string的使用&#xff0c;总感觉了解不是很深厚&#xff1b;自己模拟实现string类来帮助自己理解。 这里只是实现了一部分内容&#xff08;并没有实现完整的string类&#xff09;。 先来实现string类里面的成员变量&#xff1a; #include<iostream…

python qt5 常用

QT5中如何设置让窗口根据屏幕比例显示设置&#xff1f; desktop QDesktopWidget().screenGeometry() self.resize(int(desktop.width() * 0.3), int(desktop.height()*0.5)) QT5中关于背景穿透问题的处理方式&#xff1f; 场景如下&#xff1a;我们在开发的时候&#xff0c…

【C语言】数据类型和变量

个人主页 &#xff1a; zxctscl 如有转载请先通知 文章目录 1. 数据类型1.1 字符1.2 整型1.3 浮点型1.4 布尔类型 2. signed和unsigned3. 数据类型的取值范围4. 变量4.1 变量的创建4.2 变量的分类 5. 算术操作符&#xff1a;、-、*、/、%5.1 和 -5.2 *5.3 /5.4 % 6. 赋值操作符…

网络丢包定位记录(一)

数据在Internet上是以数据包为单位传输的&#xff0c;单位为字节&#xff0c;数据在网络上传输&#xff0c;受网络设备&#xff0c;网络质量等原因的影响&#xff0c;使得接收到的数据少于发送出去的数据&#xff0c;造成丢包。 数据包接收、发送原理 发送数据包&#xff1a; …

策略模式+模版模式+工厂模式

1. 抽象类 /*** 策略模式&#xff1a;不同类型选择不同的实现策略* */ public interface AbstractStrategy {/*** 模版模式&#xff1a;不同策略实现同一接口的共性部分&#xff08;公共方法&#xff09;* */default void commentMeth(){System.out.println("模版方法&qu…

【STM32】esp8266通过MQTT连接服务器|订阅发布

1. MQTT协议 该协议为应用层协议&#xff0c;传输层使用的是tcp,MQTT的订阅和发布&#xff0c;就相当于在抖音中你关注了某个领域的博主&#xff08;订阅&#xff09;&#xff0c;如果有其他人发了作品就会推给你&#xff08;发布&#xff09;&#xff0c;默认已经安装好了 简…

java实现LRU 缓存

如果碰到这种题⽬先不要慌张&#xff0c;现在脑海⾥回忆⼀遍 LRU 的基本概念&#xff1a;LRU&#xff08;Least Recently Used&#xff0c;最近最少使⽤&#xff09;是⼀种缓存算法&#xff0c;其核⼼思想是将最近最少使⽤的缓存项移除&#xff0c;以便为更常 ⽤的缓存项腾出空…

鸿蒙4.0(HarmonyOS 4.0)与鸿蒙Next(HarmonyOS Next)区别

鸿蒙4.0&#xff08;HarmonyOS 4.0&#xff09;与鸿蒙Next&#xff08;HarmonyOS Next&#xff09;是华为推出的两个不同版本的操作系统&#xff0c;它们之间存在一些显著的区别&#xff1a; 兼容性&#xff1a; 鸿蒙4.0&#xff1a;依然保持了对Android应用的兼容性&#xff0…