jvm 分析调优工具-学习笔记

news2024/11/24 19:01:30

jvm 分析调优工具

jps命令查看java进程pid

jps 列出java进程名(不完整类名) 和pid

在这里插入图片描述

jps -l 列出java进程名(完整类名) 和pid

在这里插入图片描述

jmap命令查看java进程占用的jvm资源情况

jmap -histo pid 查看内存情况

在这里插入图片描述

jmap -heap pid 查看java程序的堆占用信息

在这里插入图片描述

jmap -dump 导出heap快照分析文件heap.hprof

在这里插入图片描述

生成的heap.hprof文件可以使用mat工具或jvisualvm工具 进行分析。

可以在jar启动时配置 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./(指定路径)
这样就能设置内存溢出自动导出dump文件到指定的路径

mat工具是第三方厂商提供的工具,

一般使用jdk自带的jvisualvm 工具查看导出的heap.hprof文件
在这里插入图片描述

控制台输入jvisualvm命令即可打开jdk自带的可视化jvm分析工具
在这里插入图片描述

点文件->装入 ,把heap.hprof文件导入到visualVM里,就可以看到堆dump的详细信息
在这里插入图片描述

jinfo命令查看java程序的jvm参数和sys配置参数

jinfo查看java程序的jvm参数

jinfo -flags pid 可以看到程序的Xmx Xms等参数配置情况

在这里插入图片描述

jinfo查看java程序的系统参数

查看java系统参数,使用命令 jinfo -sysprops pid

在这里插入图片描述

jstat命令查看堆内存各部分的使用量已经加载类的数量

gc垃圾回收统计 jstat -gc pid

在这里插入图片描述

堆内存统计 jstat -gccapacity pid

在这里插入图片描述

新生代垃圾回收统计 jstat -gcnew pid

在这里插入图片描述

新生代内存统计 jstat -gcnewcapacity pid

在这里插入图片描述

老年代垃圾回收统计 jstat -gcold pid

在这里插入图片描述

老年代内存统计 jstat -gcoldcapacity pid

在这里插入图片描述

元数据空间统计 jstat -gcmetacapacity pid

在这里插入图片描述

垃圾回收简化 jstat -gcutil pid

在这里插入图片描述

场景1-分析线上应用OOM后生成的dump文件

线上应用的jvm启动参数配置

-Xms28m -Xmx56m -XX:+HeapDumpOnOutOfMemoryError

代码案例OOMTest.java

package cn.demo;

import java.util.ArrayList;
import java.util.List;

public class OOMTest {


    public static void main(String[] args) {
        
        List<ThirdUser>  list = new ArrayList<>();

        while (true){  //while true 死循环,会使程序一直执行
            ThirdUser thirdUser = new ThirdUser();
            thirdUser.setUsername("1");
            thirdUser.setAge(1);
            thirdUser.setHobby("ctrl");
            list.add(thirdUser); //由于配置了-Xmx56m,当程序占用的jvm内存大于56m后会报OOM
        }
    }
}

class ThirdUser {

    private String username;

    private Integer age;

    private String hobby;

    public ThirdUser() {
    }

    public ThirdUser(String username, Integer age, String hobby) {
        this.username = username;
        this.age = age;
        this.hobby = hobby;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getHobby() {
        return hobby;
    }

    public void setHobby(String hobby) {
        this.hobby = hobby;
    }

    @Override
    public String toString() {
        return "ThirdUser{" +
                "username='" + username + '\'' +
                ", age=" + age +
                ", hobby='" + hobby + '\'' +
                '}';
    }
}

启动运行后,会报错OutOfMemoryError

java.lang.OutOfMemoryError: Java heap space
Dumping heap to java_pid5768.hprof ...
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at java.util.Arrays.copyOf(Arrays.java:3210)
	at java.util.Arrays.copyOf(Arrays.java:3181)
	at java.util.ArrayList.grow(ArrayList.java:265)
	at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:239)
	at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:231)
	at java.util.ArrayList.add(ArrayList.java:462)
	at cn.demo.OOMTest.main(OOMTest.java:18)
Heap dump file created [106019329 bytes in 0.408 secs]

在这个java程序根目录下会生成 dump文件 java_pid5768.hprof ,然后,使用jvisualvm 或 jprofiler 工具进行分析hprof文件。

这里以jvisualvm工具为例,把java_pid5768.hprof导入到jvisualvm后,可以看到如下界面
在这里插入图片描述

在这里插入图片描述

场景2-利用jstack命令排查程序死锁问题

代码案例MustDeadLockDemo.java

package cn.demo;

public class MustDeadLockDemo {

    static class DeadLockTask implements Runnable{
        private boolean flag;
        private Object lock1;
        private Object lock2;
        public DeadLockTask(boolean flag, Object lock1, Object lock2) {
            this.flag = flag;
            this.lock1 = lock1;
            this.lock2 = lock2;
        }
        @Override
        public void run() {
            if (flag){
                synchronized (lock1){
                    System.out.println(Thread.currentThread().getName()+"->拿到锁1");
                    try {
                        Thread.sleep(1000);
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+"->等待锁2释放...");
                    synchronized (lock2){
                        System.out.println(Thread.currentThread().getName()+"->拿到锁2");
                    }
                }
            }
            if (!flag){
                synchronized (lock2){
                    System.out.println(Thread.currentThread().getName()+"->拿到锁2");
                    try {
                        Thread.sleep(1000);
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+"->等待锁1释放...");
                    synchronized (lock1){
                        System.out.println(Thread.currentThread().getName()+"->拿到锁1");
                    }
                }
            }
        }
    }

    public static void main(String[] args){
        Object lock1 = new Object();
        Object lock2 = new Object();
        new Thread(new DeadLockTask(true,lock1,lock2),"线程1").start();
        new Thread(new DeadLockTask(false,lock1,lock2),"线程2").start();
    }
}

这个程序执行会因为拿不到对方的锁而一直阻塞,无法结束。

首先使用 jps命令找到这个java进程的pid

jps -l

然后使用jstack 命令查看这个java进程的线程dump信息

jstack pid

在这里插入图片描述

在这里插入图片描述

解决死锁的办法:打破多线程对资源的死锁占用,使其存在先后执行、先后占用的顺序。

场景3-使用jstack找出占用cpu最高的线程堆栈信息

代码案例CpuMaxTest.java

package cn.demo;

public class CpuMaxTest {
    public static final int initData = 66;
    public static UserTest user = new UserTest();
    private UserTest user2 = new UserTest();
    public int compute(){
        int a =1;
        int b =2;
        int c = (a+b)*10;
        return c;
    }
    public static void main(String[] args) {
        CpuMaxTest test = new CpuMaxTest();
        while (true){
            test.compute();
        }
    }
}

class UserTest {
    private String uid;
    private String name;
    UserTest() {
    }
    UserTest(String uid, String name) {
        this.uid = uid;
        this.name = name;
    }
}

这个程序执行后会导致CPU占用 99%,排查步骤如下

1用 jps -l 列出java进程的进程号 和 进程名

jps -l

在这里插入图片描述

2使用命令 top -p pid ,查看这个java进程在linux的内存情况,pid是你的java进程号

top -p  8318

在这里插入图片描述

3按大写的H键 ,获取每个线程的内存情况

在这里插入图片描述

4找到内存和CPU占用最高的线程tid ,比如1804

5将1804转换成16进制,使用命令

printf '%x\n' 1804

在这里插入图片描述

6执行 如下的jstack 命令,得到线程堆栈信息中 0x2119这个线程所在行后面10行的信息。

 jstack  进程pid | grep -A 10  线程id的16进制

在这里插入图片描述

7根据上面的堆栈信息找出可能存在问题的代码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/574966.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

22 VueComponent 响应式处理

前言 这是最近的碰到的那个 和响应式相关的问题 特定的操作之后响应式对象不“响应“了 引起的一系列的文章 主要记录的是 vue 的相关实现机制 呵呵 理解本文需要 vue 的使用基础, js 的使用基础 测试用例 测试用例如下, 一个简单的 按钮事件的触发 问题的调试 数据…

老macbook升级新版本(Big sur、Monterey)

老macbook升级新版本&#xff08;Big sur、Monterey&#xff09; 一、前期须知以及准备1.摘要2.设备3.升级方法3.前期准备 二、引导U盘的搭建1.下载安装程序2.U盘格式问题3.下载系统镜像并写入U盘 三、系统安装结束语 一、前期须知以及准备 1.摘要 对于老版本的macbook一系列…

代码随想录训练营Day53| 1143.最长公共子序列 1035.不相交的线 53. 最大子序和 动态规划

目录 学习目标 学习内容 1143.最长公共子序列 1035.不相交的线 53. 最大子序和 动态规划 学习目标 1143.最长公共子序列 1035.不相交的线 53. 最大子序和 动态规划 学习内容 1143.最长公共子序列 1143. 最长公共子序列 - 力扣&#xff08;LeetCode&#xff09;ht…

PS磨皮插件免费电脑版Portraiture4.03下载及使用教程

Portraiture是一款智能磨皮插件&#xff0c;为Photoshop和Lightroom添加一键磨皮美化功能&#xff0c;快速对照片中皮肤、头发、眉毛等部位进行美化&#xff0c;Portraiture 4用于人像图片润色&#xff0c;磨皮等&#xff0c;减少了人工选择图像区域的重复劳动。它能智能地对图…

chatgpt赋能python:如何在Python中输入字符

如何在Python中输入字符 Python是一种非常流行的编程语言&#xff0c;它被广泛应用于各种领域&#xff0c;包括Web开发、人工智能、数据分析、科学计算等。在Python中输入字符是一项基本的操作&#xff0c;本文将介绍常见的输入字符方式以及注意事项。 使用input()函数输入字…

[数据结构] AVL树的插入旋转 和 概念理解

文章目录 定义 && 性质定义性质 实现思路架构节点AVL树框架Insert&#xff08;插入&#xff09;左单旋右单旋左右双旋右左双旋 定义 && 性质 定义 二叉搜索树虽可以缩短查找的效率&#xff0c;但 如果数据有序或接近有序二叉搜索树将退化为单支树&#xff0c…

初学Qt(Day04)

今日目标 创建一个类似游戏手柄的窗口&#xff0c;每次鼠标点击拖动手柄&#xff0c;在qt开发界面输出坐标&#xff0c;每当松开鼠标&#xff0c;手柄自动复位。 目标是实现类似下面这种 先说结论&#xff08;免得我又忘记了&#xff09;&#xff1a;没写完&#xff0c;是一…

Makefile基础教学(include的使用方法)

文章目录 前言一、include在makefile中的概念介绍二、include使用示例三、include中需要注意的一些操作1. 在include前加-选项2. include触发规则创建了文件会发生什么3. include包含的文件夹存在 总结 前言 本篇文章将讲解include的使用方法&#xff0c;在C语言中使用include…

chatgpt赋能python:Python与SEO的奇妙关系

Python与SEO的奇妙关系 SEO(Search Engine Optimization)&#xff0c;中文翻译为搜索引擎优化&#xff0c;是指通过对网站进行各种技术和内容方面的优化&#xff0c;来提升网站在搜索引擎自然排名中的位置&#xff0c;进而吸引更多的潜在客户。而Python语言&#xff0c;则成为…

jQuery-attr()、val()、add()属性和each函数

<!DOCTYPE HTML> <html> <head> <meta http-equiv"Content-Type" content"text/html; charsetUTF-8"> <title>jQuery-attr()、add()属性和each函数</title> <script type"text/j…

[数据集][目标检测]数据集VOC格式绝缘子缺陷检测数据集VOC-4086张

数据集格式&#xff1a;Pascal VOC格式(不包含分割路径的txt文件和yolo格式的txt文件&#xff0c;仅仅包含jpg图片和对应的xml) 图片数量(jpg文件个数)&#xff1a;4086 标注数量(xml文件个数)&#xff1a;4086 标注类别数&#xff1a;3 标注类别名称:["jueyuanzi",&…

25 VueComponent 的生命周期

前言 这是最近的碰到的那个 和响应式相关的问题 特定的操作之后响应式对象不“响应“了 引起的一系列的文章 主要记录的是 vue 的相关实现机制 呵呵 理解本文需要 vue 的使用基础, js 的使用基础 测试用例 测试用例如下, 一个简单的 按钮事件的触发 问题的调试 这里…

Linux——网络套接字3|Tcp客户端编写②

根据我们前面写的服务器,server端需要绑定,而client要不要bind呢? 不需要,因为客户端一旦和一个非常具体的端口号绑定,可能会导致端口号绑定多个客户端,因此可能会出现某个客户端无法启动。而服务器需要明确的端口号,因为服务器面对的是众多的客户端,服务器端口号一旦被…

c++ 11标准模板(STL) std::map(五)

定义于头文件<map> template< class Key, class T, class Compare std::less<Key>, class Allocator std::allocator<std::pair<const Key, T> > > class map;(1)namespace pmr { template <class Key, class T, clas…

ros学习

1创建工作空间 catkin_init_workspace 将文件夹初始化成ros文件 编译工作空间catkin_make vi ~/.bashrc 加入环境变量bashrc一下在任何终端都生效 catkin_create_pkg learning_communication通讯机制 std_msgs数据结构 rospy roscpp catkin_create_pkg mbot_description ur…

雅思备考经验!阅读 8.5,听力 8.5!

成绩单 先上热乎乎的成绩单截图&#xff08;2023.5.19 考试&#xff09;&#xff0c;偏科选手出来挨打&#xff01;好在小分都达到了要求~ 英语基础 大概是两三年前考过托福和 GRE&#xff0c;成绩过期了没办法&#xff0c;只能重考&#xff0c;这次试试雅思。 雅思和托福的…

14-Vue技术栈之Vue3快速上手

目录 1.Vue3简介2. Vue3带来了什么2.1 性能的提升2.2 源码的升级2.3 拥抱TypeScript2.4 新的特性 1、海贼王&#xff0c;我当定了&#xff01;——路飞 2、人&#xff0c;最重要的是“心”啊&#xff01;——山治 3、如果放弃&#xff0c;我将终身遗憾。——路飞 4、人的梦想是…

【软考系统规划与管理师笔记】第3篇 信息技术知识2

目录 1 计算机网络 1.1网络技术标准、协议与应用 Internet技术及应用 2 标识技术 域名系统和统一资源定位器 3 网络分类、组网和接入技术 3.1 网络分类 3.2 网络交换技术 3.3 网络接入技术 3.4 无线网络技术 4 网络服务器和网络存储技术 4.1 服务器 4.2 网络存储技…

24 memcmp 的调试

前言 同样是一个 很常用的 glibc 库函数 不管是 用户业务代码 还是 很多类库的代码, 基本上都会用到 内存数据的比较 不过 我们这里是从 具体的实现 来看一下 它的实现 主要是使用 汇编 来进行实现的, 因此 理解需要一定的基础 测试用例 就是简单的使用了一下 memcpy,…

【Python】正则表达式应用

知识目录 一、写在前面✨二、姓名检查三、解析电影排行榜四、总结撒花&#x1f60a; 一、写在前面✨ 大家好&#xff01;我是初心&#xff0c;希望我们一路走来能坚守初心&#xff01; 今天跟大家分享的文章是 正则表达式的应用 &#xff0c;希望能帮助到大家&#xff01;本篇…