6. JVM调优工具详解及调优实战

news/2024/10/27 22:27:11/

JVM性能调优

  • 1. 前置启动程序
    • 1.1 Jmap
      • 1.1.1 Jmap查询内存信息
      • 1.1.2 Jmap查询堆信息
      • 1.1.3 jmap查询堆内存dump
    • 1.2 Jstack
    • 1.3 远程连接jvisualvm

本文是按照自己的理解进行笔记总结,如有不正确的地方,还望大佬多多指点纠正,勿喷。

课程内容:

1、Jmap,Jstack,Jinfo命令详解

2、Jvisualvm调优工具实战

3、JVM内存或CPU飙高如何快速定位

4、Jstat命令预估JⅣVM运行情况

5、系统频繁Full GC导致系统卡顿实战调优

6、内存泄露到底是怎么回事

1. 前置启动程序

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

因此为了后续使用,我们直接从创建一个web项目开始,该部分知识是为了复习之前所学内容。

  1. 创建一个springboot项目
    ①. 首先打开idea,找到new module
    在这里插入图片描述
    ②. 点击next,填入下列信息
    在这里插入图片描述
    在这里插入图片描述
    ③. 点击下一步继续选择
    在这里插入图片描述
    ④. 继续下一步,检查信息
    在这里插入图片描述
    ⑤. 完成(如果包加载的特别慢,记得配置一下maven)
    在这里插入图片描述

  2. 写一个简单的小例子
    ①写一段代码

package com.ding.controller;import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/books")
public class BookController {@GetMappingpublic String getById(){System.out.println("springboot is running.......");return "springboot is running........";}
}

② 运行启动类
在这里插入图片描述

③ 访问成功
在这里插入图片描述
注意事项:记得把启动类与文件放的目录关系
在这里插入图片描述

  1. 将该项目打包成jar项目

在这里插入图片描述

我们现在启动该jar包。

找到文件的位置

在这里插入图片描述

java -jar jvm03-0.0.1-SNAPSHOT.jar

在这里插入图片描述
然后这个界面就可以访问了
在这里插入图片描述

1.1 Jmap

1.1.1 Jmap查询内存信息

  1. 用jps查看其进程id

在这里插入图片描述

此命令可以用来查看内存信息,示例个数以及占用内存大小。

jmap -histo 21480(进程号)

在这里插入图片描述

其实一般这样就可以了,但是这样不好看,所以我们可以把他写到一个文件里面。

jmap -histo 21480 > ./log.txt 

这样就打印到D盘去了

在这里插入图片描述

  • 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[][]

1.1.2 Jmap查询堆信息

jmap -heap 21480

在这里插入图片描述

1.1.3 jmap查询堆内存dump

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

在这里插入图片描述

导出的信息:

在这里插入图片描述
这个信息的作用是等一会可以导到可视化工具里面的。例如jvisualvm。

在这里插入图片描述
进入之后是这个界面

在这里插入图片描述

在这个里面它可以装入文件,就是刚才我们所生成的文件。

在这里插入图片描述

我们就可以看到我们当时保存快照时候的堆信息情况

在这里插入图片描述

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

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

示例代码:(这个代码是我又写的,不是那个jar里面的)

package ding;import java.util.ArrayList;
import java.util.List;
import java.util.UUID;public class OOMTest {public static List<Object> list = new ArrayList<>();public static void main(String[] args) {//ArrayList<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());}}
}

这个程序我们知道肯定会溢出,但是我们假如这两个参数,在快溢出的时候会导出一个快照文件。

现在来验证一下,首先配置一下,把内存设置的小一点,方便他溢出

-Xms10M -Xmx10M -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:\jvm.dump

在这里插入图片描述
运行之前D盘是没有那个jvm.dump文件的,运行之后就会产生。

在这里插入图片描述

现在我们把这个文件导入到那个jvisualvm工具中。

在这里插入图片描述
导入之后就可以看到什么类比较多,看主要是谁占的内存比较多

在这里插入图片描述

1.2 Jstack

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

package ding;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){System.out.println("thread1 begin");try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}synchronized (lock2){System.out.println("thread1 end");}}}).start();new Thread(()->{synchronized (lock2){System.out.println("thread2 begin");try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}synchronized (lock1){System.out.println("thread2 end");}}}).start();System.out.println("main thread end");}
}

在运行的时候能看到程序一直在运行,但是不动,发生了死锁。

在这里插入图片描述

这个时候就可以使用jstack命令去看到底是怎么回事。

查询一下进程号

在这里插入图片描述

这个时候就可以看到详细信息

在这里插入图片描述

  • “Thread-1” 线程名

  • prio=5 优先级=5

  • tid=Ox000000001fa9e000 线程id

  • nid=Ox2d64 线程对应的本地线程标识

  • nidjava.lang.Thread.State: BLOCKED 线程状态

并且在这个详细信息里面会提示发现死锁

在这里插入图片描述
也可以使用jvisualvm也可以直接检测到死锁。我们打开这个工具他会自动识别这个进程。

立马能显示检测到死锁(我这个中间我把这个进程杀死了,重新启动的,进程id变化了一下哈,但是不影响实验)

在这里插入图片描述
点击上图右上角的线程dump可以看到详细的信息。就是和我们的那个刚才黑窗口里面的信息是一样的。

1.3 远程连接jvisualvm

启动普通的jar程序JMX端口配置:

java ‐Dcom.sun.management.jmxremote.port=8888Djava.rmi.server.hostname=192.168.50.60Dcom.sun.management.jmxremote.ssl=falseDcom.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=8888Djava.rmi.server.hostname=192.168.50.60Dcom.sun.management.jmxremote.ssl=falseDcom.sun.management.jmxremote.authenticate=false

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

systemctl stop firewalld #临时关闭防火墙

http://www.ppmy.cn/news/216196.html

相关文章

spring注解驱动开发(BEAN注册方式与生命周期)

目录 容器中注册BEAN的方式 BEAN生命周期 容器中注册BEAN的方式 包扫描组件标注注解 ComponentScan(basePackages {"com.an.spring.condition"}) Service Component Controller RepositoryBEan方式【导入第三方包里面的组件】 ComponentScan(basePackages {&quo…

php获取文件的权限信息(获取权限信息、返回字符串涵义、二进制的转换方式、权限修改)

php获取文件的权限信息 说明1.获取文件的权限信息2.返回文件权限字符的解读3.转为二进制权限4.修改权限 说明 &#xff08;图片来源于网络&#xff09; 文件权限是指文件或目录对用户和其他进程的访问许可。在 Unix 和 Linux 系统中&#xff0c;文件和目录都有三个权限&#x…

【Web】云安全之元数据服务

前言 最近再挖SRC的时候&#xff0c;遇到了一处疑似SSRF的接口&#xff0c;并且尝试访问元数据服务&#xff0c;通的&#xff0c;但由于之前接触的较少&#xff0c;暂时没有思路&#xff0c;所以有了如下的文章。 本文详细介绍了元数据相关的一些知识点&#xff0c;以及如何通…

法规标准-UN R158标准解读

UN R158是做什么的&#xff1f; UN R158全名为针对驾驶员识别车辆后方弱势道路使用者&#xff0c;联合国对倒车系统和机动车的统一规定&#xff0c;该法规涉及批准倒车和机动车辆的装置&#xff0c;主要为保证倒车时避免碰撞&#xff0c;方便驾驶员观察了解车辆后部人员和物体…

完美解决小米笔记本风扇乱转的问题

在平衡模式下更改高级电源设置--->处理器电源管理--->最大出来状态 改成88%,或者改成低于88%; 转载于:https://my.oschina.net/u/1385936/blog/1815100

笔记本风扇声音大(处理器电源管理)

首先打开控制面板&#xff0c;打开“电源选项”&#xff0c; 点击“更改计划设置”&#xff0c; 点击“更改高级电源设置”&#xff0c; 点击“处理器电源管理”前的号&#xff0c; 系统散热方式全部改为“被动”&#xff0c; 最大处理器状态改99%。 Tips&#xff1a;如果没有…

戴尔笔记本——减低风扇声音的一种办法

1.在windows搜索框中&#xff0c;搜索Dell Power Manager&#xff0c;并打开其软件。 2.打开“散热管理”&#xff0c;选中“静音模式”&#xff0c;这样就可以长期风扇声音小了。若想让电脑风扇声音瞬间消失&#xff0c;则可以选择“疾速模式”&#xff0c;但这种模式下&…

笔记本更换散热风扇及硅胶

注意事项&#xff1a; 1&#xff1a;拆机更换有开不了机的风险 2&#xff1a;一定要单买导热系数高的散热硅胶 一&#xff1a;买一对风扇&#xff0c;cpu跟显卡散热风扇一对。 二&#xff1a;买散热系数高的硅胶&#xff0c;不要用送的 三&#xff1a;拆机更换 四&#xf…