当前位置: 首页 > news >正文

10-JVM调优工具详解

上一篇:09-JVM垃圾收集底层算法实现

前置启动程序
事先启动一个web应用程序,用jps查看其进程id,接着用各种jdk自带命令优化应用

1.Jmap

此命令可以用来查看内存信息,实例个数以及占用内存大小
在这里插入图片描述

jmap -histo 14660  #查看历史生成的实例
jmap -histo:live 14660  #查看当前存活的实例,执行过程中可能会触发一次full gc

打开log.txt,文件内容如下:
在这里插入图片描述

  • num:序号
  • instances:实例数量
  • bytes:占用空间大小
  • class name:类名称,[C is a char[],[S is a short[],[I is a int[],[B is a byte[],[[I is a int[][]

2.堆信息

在这里插入图片描述

3.堆内存dump

jmap -dump:format=b,file=eureka.hprof 14660

在这里插入图片描述

也可以设置内存溢出自动导出dump文件(内存很大的时候,可能会导不出来)

  • -XX:+HeapDumpOnOutOfMemoryError
  • -XX:HeapDumpPath=./ (路径)

示例代码:

public class OOMTest {public static List<Object> list = new ArrayList<>();// JVM设置    // -Xms10M -Xmx10M -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:\jvm.dump public static void main(String[] args) {List<Object> list = new ArrayList<>();int i = 0;int j = 0;while (true) {list.add(new User(i++, UUID.randomUUID().toString()));new User(j--, UUID.randomUUID().toString());}}
}

可以用jvisualvm命令工具导入该dump文件分析
在这里插入图片描述

4.Jstack

用jstack加进程id查找死锁,见如下示例

public class DeadLockTest {private static Object lock1 = new Object();private static Object lock2 = new Object();public static void main(String[] args) {new Thread(() -> {synchronized (lock1) {try {System.out.println("thread1 begin");Thread.sleep(5000);} catch (InterruptedException e) {}synchronized (lock2) {System.out.println("thread1 end");}}}).start();new Thread(() -> {synchronized (lock2) {try {System.out.println("thread2 begin");Thread.sleep(5000);} catch (InterruptedException e) {}synchronized (lock1) {System.out.println("thread2 end");}}}).start();System.out.println("main thread end");}
}

在这里插入图片描述

“Thread-1” 线程名
prio=5 优先级=5
tid=0x000000001fa9e000 线程id
nid=0x2d64 线程对应的本地线程标识nid
java.lang.Thread.State: BLOCKED 线程状态

在这里插入图片描述

还可以用jvisualvm自动检测死锁
在这里插入图片描述

远程连接jvisualvm
启动普通的jar程序JMX端口配置:

java -Dcom.sun.management.jmxremote.port=8888 -Djava.rmi.server.hostname=192.168.65.60 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -jar microservice-eureka-server.jar

PS:

  • -Dcom.sun.management.jmxremote.port 为远程机器的JMX端口
  • -Djava.rmi.server.hostname 为远程机器IP

tomcat的JMX配置:在catalina.sh文件里的最后一个JAVA_OPTS的赋值语句下一行增加如下配置行

JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote.port=8888 -Djava.rmi.server.hostname=192.168.50.60 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false"

连接时确认下端口是否通畅,可以临时关闭下防火墙

systemctl stop firewalld   #临时关闭防火墙

Jstack找出占用cpu最高的线程堆栈信息

/*** 运行此代码,cpu会飙高*/
public class Math {public static final int initData = 666;public static User user = new User();public int compute() {  //一个方法对应一块栈帧内存区域int a = 1;int b = 2;int c = (a + b) * 10;return c;}public static void main(String[] args) {Math math = new Math();while (true){math.compute();}}
}
  1. 使用命令top -p ,显示你的java进程的内存情况,pid是你的java进程号,比如19663
    在这里插入图片描述

  2. 按H,获取每个线程的内存情况
    在这里插入图片描述

  3. 找到内存和cpu占用最高的线程tid,比如19664

  4. 转为十六进制得到 0x4cd0,此为线程id的十六进制表示

  5. 执行 jstack 19663|grep -A 10 4cd0,得到线程堆栈信息中 4cd0 这个线程所在行的后面10行,从堆栈中可以发现导致cpu飙高的调用方法

在这里插入图片描述

  1. 查看对应的堆栈信息找出可能存在问题的代码

5.Jinfo

查看正在运行的Java应用程序的扩展参数
查看jvm的参数
在这里插入图片描述

查看java系统参数
在这里插入图片描述

6.Jstat

jstat命令可以查看堆内存各部分的使用量,以及加载类的数量。命令的格式如下:

jstat [-命令选项] [vmid] [间隔时间(毫秒)] [查询次数]

注意:使用的jdk版本是jdk8

下一篇:11-JVM调优实战-1

http://www.lryc.cn/news/158901.html

相关文章:

  • 东方博易oj——3119 - 约瑟夫问题2(链表)
  • C++,day0907
  • 孤儿僵尸守护进程的简单理解
  • 学习笔记——Java入门第一季
  • 更改注册表exe值后的惨痛经历
  • stable diffusion实践操作-LyCORIS
  • 无需公网IP教你如何外网远程访问管家婆ERP进销存
  • Swift使用编解码库Codable
  • Vue + Element UI 前端篇(三):工具模块封装
  • 【pytorch】数据加载dataset和dataloader的使用
  • 搭建单机版FastDFS分布式文件存储系统
  • 【验证码逆向专栏】房某下登录滑块逆向分析
  • Python 3.11 版本是对线程安全做了什么更改吗
  • 【Docker】镜像的创建、管理与发布
  • 移动硬盘或U盘无法弹出的解决方法
  • (leetcode1761一个图中连通三元组的最小度数,暴力+剪枝)-------------------Java实现
  • 【漏洞复现】金和OA C6任意文件读取漏洞
  • 2023年全国大学生数学建模B题
  • 【LeetCode】2651.计算列车到站时间
  • Redis——认识Redis
  • 通讯录怎么导入新手机?3个推荐小妙招
  • Geoserver发布shp、tiff、瓦片等格式的GIS数据
  • 读书笔记-《ON JAVA 中文版》-摘要24[第二十一章 数组]
  • go语言基本操作---五
  • 【sgLazyTree】自定义组件:动态懒加载el-tree树节点数据,实现增删改、懒加载及局部数据刷新。
  • Rust个人学习笔记
  • Java根据身份证号码提取出省市区,JSON数据格式
  • MySQL知识笔记——初级基础(实施工程师和DBA工作笔记)
  • javaee 事务的传播行为
  • C#-SQLite-使用教程笔记