JDK 命令行工具与可视化工具,linux 基础教程第二版课后答案
示例一:一段死循环 ava 程序,模拟 linux 环境下疯狂占用 cpu 资源
improt java.util.Random;
public class demo {
public static void main(String[] args) {
while(true){
System.out.println(new Random().nextInt(77778888));
}
}
}
复制代码
查看系统状况:用 top 命令去查各个进程 CPU、内存的资源消耗情况,找出最耗资源的进程 pid,如图所示,最耗资源的是 java 进程,pid 是 2818【需要在后台运行很长时间才会有反应…】
定位到问题线程:定位到具体的问题线程 ps -mp pid -o THREAD,tid,time 如图所示在 java 进程中 2819 的线程最耗资源
查看问题线程的堆栈信息:先将线程 id 转换为 16 进制(英文小写格式) printf “%x\n” 问题线程的 id 转为 16 进制英文小写
在使用 jstack 查看线程的堆栈信息 jstack pid |grep tid -A60
由此便可以查看到是 demo.java 中的第六行出了问题【此处只是小 demo 去模拟程序死循环,CPU 线上预警出现的可能性很多,常见的还有内存泄露、死锁、频繁 GC…需要结合 linux 命令和 java 命令和实际情况进行逐步排查】
[](
)jinfo:查看/设置虚拟机的参数
jinfo 可以查看 JVM 的参数,并允许在程序运行期间修改 JVM 的参数,这样 JVM 就不用重启了。
使用格式: jinfo [option] pid ,可以通过-flag[+|-] name 添加和删除一些参数,或者-flag name =value 修改一些参数,但是很多参数是不允许修改的
public class DEMO04 {
public static void main(String[] args) throws IOException {
System.out.println(“jinfo”);
System.in.read();
}
}
复制代码
[](
)jmap:生成 dump 文件
jmap 用于生成一份堆存储快照(dump),把 Java 堆区的使用情况快照一份导出来供我们排查问题。
使用格式 : jmap [option] vmid
示例:
public class DEMO05 {
public static void main(String[] args) throws IOException {
System.out.println(“jmap”);
System.in.read();
}
}
复制代码
显示堆区的详细信息 jmap -heap pid
生成堆快照存储文件,format=b 生成的是二进制文件, jmap -dump:live,format=b,file=D:\jmap.bin pid
[](
)jhat:虚拟机存储快照分析工具
使用 jmap 将堆区的快照文件导出后,可以使用 jhat 进行分析,不过 jhat 现在使用较少。
使用格式: jhat [-stack ] [-refs ] [-port ] [-baseline ] [-debug ] [-version] [-h|-help]
示例:
[](
)可视化工具
[](
)jconcle
作用:查看 Java 应用程序运行时情况,监视垃圾收集器的内存变化趋势,以及监视程序内的线程。
[](
)示例一:JConsole 演示内存变化
public class DEMO07 {
public static void main(String[] args) throws IOException, InterruptedException {
Thread.sleep(5000);
System.out.println(“start…”);
test();
System.in.read();
}
public static void test() throws InterruptedException {
final int _128K = 128 * 1024;
List<byte[]> list = new ArrayList<>();
for (int i = 0; i < 10000; i++) {
//耗时操作,令监视器的曲线变化更加明显
Thread.sleep(100);
list.add(new byte[_128K]);
}
}
}
复制代码
在控制台输入 jconsole 即可启动 JConsole 客户端
JConsole 客户端包括概览、内存、线程、类、VM 概要、MBean 这大块。
概览:主要运行数据的概览,包括堆内存,线程,类,CPU 使用情况四项信息的变化趋势图
内存:JDK 为 1.8,使用的垃圾收集器为 ParallerScavenge+Parallel Old,可以监视堆内存以及其中各个区域(Eden 区,Survivor 区,老年代)的变化趋势,还可以监视非堆(元空间)的内存变化趋势,相当于命令行中的 jstat
png)
线程:可以查看当前程序有哪些线程在运行,单机可以查看线程的堆栈信息,相当于命令行工具的 jstack,其左下角还有检测死锁的按钮。
类:如图所示,显示了系统以及装载的类数量。在详细信息栏中,还显示了已卸载的类数量。
类:如图所示,显示了系统以及装载的类数量。在详细信息栏中,还显示了已卸载的类数量。
示例二:JConcle 示例死循环、阻塞等待、死锁现象
import java.io.IOException;
import java.util.concurrent.TimeUnit;
public class DEMO08 {
public static void main(String[] args) throws IOException {
System.in.read();
System.out.println("开启死循环线程");
whileTureThread();
System.in.read();
System.out.println("开启等待线程");
waitThread();
System.in.read();
System.out.println("开启死锁线程");
deadLock();
}
/**
死循环线程
*/
private static void whileTureThread() {
new Thread(() -> {
while (true) {
}
}, "whileTrueThread").start();
}
/**
等待线程
*/
private static void waitThread() {
new Thread(() -> {
synchronized (DEMO08.class) {
try {
DEMO08.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"waitThread").start();
}
/**
模拟死锁现象
*/
private static void deadLock() {
String A = "A";
String B = "B";
new Thread(() -> {
synchronized (A) {
try {
//睡 2 秒
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (B) {
System.out.println("拿到 B 锁");
}
}
}, "A").start();
new Thread(() -> {
synchronized (B) {
try {
评论