Java内存分析相关工具

简介: Java内存分析相关工具


1、jstack(打印线程快照)

jstack 是 JVM 自带的 Java 堆栈跟踪工具,它用于打印出给定的 java 进程ID、core file、远程调试服务的Java堆栈信息。jstack 命令用于生成虚拟机当前时刻的线程快照。

命令格式:

  1. jstack [ option ] pid    // 打印某个进程的堆栈信息
  2. jstack [ option ] executable core
  3. jstack [ option ][server-id@]remote-hostname-or-IP

 

 


2、jps 工具(列出java进程)

jps(Java Virtual Machine Process Status Tool)是JDK提供的一个可以列出正在运行的Java虚拟机的进程信息的命令行工具,它可以显示 Java 虚拟机进程的执行主类(Main Class,main()函数所在的类)名称、本地虚拟机唯一ID(LVMID,Local Virtual Machine Identifier)等信息。另外,jps命令只能显示它有访问权限的Java进程的信息。

通过 jps 命令可以查看当前系统中有哪些 java 进程。

 

命令语法:

  1. jps [-q][-mlvV][hostid]

  2. jps [-help]

命令参数说明:

  • -q:不显示主类名称、JAR文件名和传递给主方法的参数,只显示本地虚拟机唯一ID。
  • -mlvV:我们可以指定这些参数的任意组合。
  • -m:显示Java虚拟机启动时传递给main()方法的参数。
  • -l:显示主类的完整包名,如果进程执行的是JAR文件,也会显示JAR文件的完整路径。
  • -v:显示Java虚拟机启动时传递的JVM参数。
  • -V:不显示主类名称、JAR文件名和传递给主方法的参数,只显示本地虚拟机唯一ID。
  • hostid:指定的远程主机,可以是ip地址和域名, 也可以指定具体协议,端口。如果不指定,则显示本机的Java虚拟机的进程信息。
  • -help:显示jps命令的帮助信息。

 


3、jmap 工具(查看堆内存快照)

jmap(Java Virtual Machine Memory Map)是 JDK 提供的一个可以生成 Java 虚拟机的堆转储快照 dump 文件的命令行工具。

通过命令:jmap - heap 进程id 可以查看堆内存占用情况。

命令语法:

  1. jmap [options] pid
  • pid:要打印配置信息的Java虚拟机的进程ID。
  • option:jmap命令的可选参数。如果没有指定这个参数,jinfo命令会显示Java虚拟机进程的内存映像信息,如下图:

 


3.1、常见参数


3.1.1、jmap -heap pid

显示Java堆的如下信息:

  • 被指定的垃圾回收算法的信息,包括垃圾回收算法的名称和垃圾回收算法的详细信息。
  • 堆的配置信息,可能是由命令行选项指定,或者由Java虚拟机根据服务器配置选择的。
  • 堆的内存空间使用信息,包括分代情况,每个代的总容量、已使用内存、可使用内存。如果某一代被继续细分(例如,年轻代),则包含细分的空间的内存使用信息。

代码演示,通过以下步骤演示使用 jmap 分析代码执行过程中的堆内存。

  1. package cn.itcast.jvm.t1.heap;

  2. /**
  3. * 演示堆内存
  4. */
  5. publicclassDemo1_4{

  6.    publicstaticvoid main(String[] args)throwsInterruptedException{
  7.        System.out.println("1...");
  8.        Thread.sleep(30000);
  9.        byte[] array =newbyte[1024*1024*10];// 10 Mb
  10.        System.out.println("2...");
  11.        Thread.sleep(20000);
  12.        array =null;
  13.        System.gc();
  14.        System.out.println("3...");
  15.        Thread.sleep(1000000L);
  16.    }
  17. }

以上代码将依次输出1、2、3,如下:

我们将依次在程序输出1、2、3时打印出此时的堆内存。

如下,在输出 1 时打印的堆内存,可以看到此时程序刚开始启动,堆内存占用并不大。

 

在输出 2 时打印堆内存如下,因为此时已经创建了一个 10m 大小的字节数组对象,所以可以看到堆内存增加了差不多 10m 的大小。

 

在输出 3 时打印堆内存如下,因为此时我们没有代码指向那个字节数组对象,并且主动调用了垃圾回收,所以可以看到堆内存减少了差不多 10m 的大小,这是因为那个字节数组对象被垃圾回收掉了。

 


4、jconsole(监控内存、CPU等指标)

Jconsole 是 jdk 自带的一套java虚拟机执行状况监视器,它能够用来监控虚拟机的内存,线程,cpu使用情况以及相关的java进程相关的MBean。jconsole 跟 jmap 不一样,jconsole 可以一直监控内存等情况,而 jmap 只是打印出当前时刻的堆内存情况,相对来说 jconsole 更好用些。

在命令中直接输入 jconsole 即可弹出 jconsole 窗口,主界面示例以下:

 

演示,假如我们执行以下代码:

  1. package cn.itcast.jvm.t1.heap;

  2. /**
  3. * 演示堆内存
  4. */
  5. publicclassDemo1_4{

  6.    publicstaticvoid main(String[] args)throwsInterruptedException{
  7.        System.out.println("1...");
  8.        Thread.sleep(30000);
  9.        byte[] array =newbyte[1024*1024*10];// 10 Mb
  10.        System.out.println("2...");
  11.        Thread.sleep(20000);
  12.        array =null;
  13.        System.gc();
  14.        System.out.println("3...");
  15.        Thread.sleep(1000000L);
  16.    }
  17. }

在启动 main 方法后,在命令行中直接输入 jconsole,可以看到堆内存的趋势,如下:

可以看到,堆内存在一个时间点急剧上升,这是因为我们创建了一个接近 10m 的字节数组对象,然后又在一个时间点急剧下降,这是因为此时那个字节数组对象已经没有引用,并且我们主动调用了垃圾回收,所以可以看到堆内存减少了差不多 10m 的大小,。

 

启动 jconsole 时,可以选择本地连接,然后选择对应的程序,如下,连接后提示不安全的连接直接点击确定即可。

 


5、jvisualvm(性能分析工具)

jvisualvm 是 JDK 自带的 JAVA 性能分析工具,它默认已经在你的JDK bin目录里了,只要你使用的是JDK1.6 Update7之后的版本,点击一下jvisualvm.exe图标它就可以运行了,如 E:\Develop\jdk1.8.0_202\bin\jvisualvm.exe 。

如演示分析以下代码执行垃圾回收后,内存占用仍然很高

  1. package cn.itcast.jvm.t1.heap;

  2. import java.util.ArrayList;
  3. import java.util.List;

  4. /**
  5. * 演示查看对象个数 堆转储 dump
  6. */
  7. publicclassDemo1_13{

  8.    publicstaticvoid main(String[] args)throwsInterruptedException{
  9.        List<Student> students =newArrayList<>();
  10.        for(int i =0; i <200; i++){
  11.            students.add(newStudent());
  12. //            Student student = new Student();
  13.        }
  14.        Thread.sleep(1000000000L);
  15.    }
  16. }
  17. classStudent{
  18.    privatebyte[] big =newbyte[1024*1024];
  19. }

启动上面 java 程序后,在命令行输入 jvisualvm 打开分析工具,如下:

 


6、通过 MAT 内存分析工具排查

参考:https://blog.csdn.net/AikesLs/article/details/124290879

  1. -XX:+HeapDumpOnOutOfMemoryError参数表示当JVM发生OOM时,自动生成DUMP文件。
  2. -XX:HeapDumpPath=${目录}参数表示生成DUMP文件的路径,也可以指定文件名称,例如:-XX:HeapDumpPath=${目录}/java_heapdump.hprof。如果不指定文件名,默认会在项目根目录下生成一个文件,文件名格式为:java_<pid>_<date>_<time>_heapDump.hprof

 


6.1、MAT工具的介绍

想要深入的进行分析并确定内存泄漏,就要分析疑似发生内存泄漏时所生成堆存储文件(hprof)。堆存储文件可以使用DDMS或者Memory Monitor来生成,输出的文件格式为hpof,而MAT就是来分析堆存储文件的。

MAT(Memory Analyzer Tool)工具是一款功能强大的]ava堆内存分析器。可以用于查找内存泄漏以及查看内存消耗情况。MAT是基于Eclipse开发的,不仅可以单独使用,还可以作为插件的形式嵌入在Eclipse中使用。

下载地址 : https://www.eclipse.org/mat/downloads.php(当使用 MAT 工具报错 jdk 版本过低时,此时可以参考:https://blog.csdn.net/health7788/article/details/123893540 指定该工具使用其他版本的 jdk。)

 


6.2、MAT工具的基本使用

用mat打开hprof文件后会看到的是一个饼状图,它主要用来显示内存的消耗,饼状图的彩色区域代表被分配的内存,灰色区域的则是空闲内存,点击每个彩色区域可以看到这块区域的详细信息,

 


6.3、MAT工具的视图

MAT 几个比较重要的视图:直方图视图(histogram)、支配树视图(dominator tree)、Leak Suspects

 


6.3.1、直方图视图(histogram)

查看对象占用的内存大小

 

 

 

生成我们大对象堆内存占用情况的一个列表。

  • Shallow Heap:大对象占用的堆内存大小
  • Retained Heap:与这个大对象关联的堆内存大小

 


6.3.2、支配树视图(dominator tree)

 

 


6.3.3、Leak Suspects

Leak Suspects :查看内存泄露的线程以及详细堆栈信息

 

 

 

在MAT工具中一般用到比较多的2个功能
1、Histogram
2、Leak Suspects


Histogram

 


Leak Suspects

Leak Suspects 界面提示可能存在内存的泄露。有的时候具体代码的位置都帮我们定位好了,排查非常方便。

 


最后,大家想获取更多知识的,可以继续关注公众号,不定时推送。分享了这么牛逼的知识,还不请小编喝个水吗,哈哈哈,欢迎土豪直接赏赞,谢谢,您的支持就是小编最大的动力。

相关文章
|
13天前
|
Web App开发 监控 JavaScript
监控和分析 JavaScript 内存使用情况
【10月更文挑战第30天】通过使用上述的浏览器开发者工具、性能分析工具和内存泄漏检测工具,可以有效地监控和分析JavaScript内存使用情况,及时发现和解决内存泄漏、过度内存消耗等问题,从而提高JavaScript应用程序的性能和稳定性。在实际开发中,可以根据具体的需求和场景选择合适的工具和方法来进行内存监控和分析。
|
14天前
|
存储 Java 编译器
Java内存模型(JMM)深度解析####
本文深入探讨了Java内存模型(JMM)的工作原理,旨在帮助开发者理解多线程环境下并发编程的挑战与解决方案。通过剖析JVM如何管理线程间的数据可见性、原子性和有序性问题,本文将揭示synchronized关键字背后的机制,并介绍volatile关键字和final关键字在保证变量同步与不可变性方面的作用。同时,文章还将讨论现代Java并发工具类如java.util.concurrent包中的核心组件,以及它们如何简化高效并发程序的设计。无论你是初学者还是有经验的开发者,本文都将为你提供宝贵的见解,助你在Java并发编程领域更进一步。 ####
|
9天前
|
缓存 算法 Java
本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制
在现代软件开发中,性能优化至关重要。本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制。通过调整垃圾回收器参数、优化堆大小与布局、使用对象池和缓存技术,开发者可显著提升应用性能和稳定性。
30 6
|
8天前
|
开发框架 监控 .NET
【Azure App Service】部署在App Service上的.NET应用内存消耗不能超过2GB的情况分析
x64 dotnet runtime is not installed on the app service by default. Since we had the app service running in x64, it was proxying the request to a 32 bit dotnet process which was throwing an OutOfMemoryException with requests >100MB. It worked on the IaaS servers because we had the x64 runtime install
|
18天前
|
Web App开发 JavaScript 前端开发
使用 Chrome 浏览器的内存分析工具来检测 JavaScript 中的内存泄漏
【10月更文挑战第25天】利用 Chrome 浏览器的内存分析工具,可以较为准确地检测 JavaScript 中的内存泄漏问题,并帮助我们找出潜在的泄漏点,以便采取相应的解决措施。
127 9
|
13天前
|
存储 缓存 安全
Java内存模型(JMM):深入理解并发编程的基石####
【10月更文挑战第29天】 本文作为一篇技术性文章,旨在深入探讨Java内存模型(JMM)的核心概念、工作原理及其在并发编程中的应用。我们将从JMM的基本定义出发,逐步剖析其如何通过happens-before原则、volatile关键字、synchronized关键字等机制,解决多线程环境下的数据可见性、原子性和有序性问题。不同于常规摘要的简述方式,本摘要将直接概述文章的核心内容,为读者提供一个清晰的学习路径。 ####
35 2
|
14天前
|
存储 安全 Java
什么是 Java 的内存模型?
Java内存模型(Java Memory Model, JMM)是Java虚拟机(JVM)规范的一部分,它定义了一套规则,用于指导Java程序中变量的访问和内存交互方式。
36 1
|
17天前
|
存储 Java 关系型数据库
在Java开发中,数据库连接是应用与数据交互的关键环节。本文通过案例分析,深入探讨Java连接池的原理与最佳实践
在Java开发中,数据库连接是应用与数据交互的关键环节。本文通过案例分析,深入探讨Java连接池的原理与最佳实践,包括连接创建、分配、复用和释放等操作,并通过电商应用实例展示了如何选择合适的连接池库(如HikariCP)和配置参数,实现高效、稳定的数据库连接管理。
34 2
|
18天前
|
Java 关系型数据库 数据库
面向对象设计原则在Java中的实现与案例分析
【10月更文挑战第25天】本文通过Java语言的具体实现和案例分析,详细介绍了面向对象设计的五大核心原则:单一职责原则、开闭原则、里氏替换原则、接口隔离原则和依赖倒置原则。这些原则帮助开发者构建更加灵活、可维护和可扩展的系统,不仅适用于Java,也适用于其他面向对象编程语言。
12 2
|
3月前
|
存储 编译器 C语言
【C语言篇】数据在内存中的存储(超详细)
浮点数就采⽤下⾯的规则表⽰,即指数E的真实值加上127(或1023),再将有效数字M去掉整数部分的1。
370 0