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 界面提示可能存在内存的泄露。有的时候具体代码的位置都帮我们定位好了,排查非常方便。

 


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

相关文章
|
19天前
|
安全 Java 程序员
深入理解Java内存模型与并发编程####
本文旨在探讨Java内存模型(JMM)的复杂性及其对并发编程的影响,不同于传统的摘要形式,本文将以一个实际案例为引子,逐步揭示JMM的核心概念,包括原子性、可见性、有序性,以及这些特性在多线程环境下的具体表现。通过对比分析不同并发工具类的应用,如synchronized、volatile关键字、Lock接口及其实现等,本文将展示如何在实践中有效利用JMM来设计高效且安全的并发程序。最后,还将简要介绍Java 8及更高版本中引入的新特性,如StampedLock,以及它们如何进一步优化多线程编程模型。 ####
21 0
|
23天前
|
Java 开发者 微服务
Spring Boot 入门:简化 Java Web 开发的强大工具
Spring Boot 是一个开源的 Java 基础框架,用于创建独立、生产级别的基于Spring框架的应用程序。它旨在简化Spring应用的初始搭建以及开发过程。
43 6
Spring Boot 入门:简化 Java Web 开发的强大工具
|
21天前
|
存储 监控 算法
Java内存管理深度剖析:从垃圾收集到内存泄漏的全面指南####
本文深入探讨了Java虚拟机(JVM)中的内存管理机制,特别是垃圾收集(GC)的工作原理及其调优策略。不同于传统的摘要概述,本文将通过实际案例分析,揭示内存泄漏的根源与预防措施,为开发者提供实战中的优化建议,旨在帮助读者构建高效、稳定的Java应用。 ####
34 8
|
19天前
|
存储 监控 算法
深入探索Java虚拟机(JVM)的内存管理机制
本文旨在为读者提供对Java虚拟机(JVM)内存管理机制的深入理解。通过详细解析JVM的内存结构、垃圾回收算法以及性能优化策略,本文不仅揭示了Java程序高效运行背后的原理,还为开发者提供了优化应用程序性能的实用技巧。不同于常规摘要仅概述文章大意,本文摘要将简要介绍JVM内存管理的关键点,为读者提供一个清晰的学习路线图。
|
23天前
|
存储 算法 Java
Java 内存管理与优化:掌控堆与栈,雕琢高效代码
Java内存管理与优化是提升程序性能的关键。掌握堆与栈的运作机制,学习如何有效管理内存资源,雕琢出更加高效的代码,是每个Java开发者必备的技能。
48 5
|
21天前
|
存储 算法 Java
Java内存管理深度解析####
本文深入探讨了Java虚拟机(JVM)中的内存分配与垃圾回收机制,揭示了其高效管理内存的奥秘。文章首先概述了JVM内存模型,随后详细阐述了堆、栈、方法区等关键区域的作用及管理策略。在垃圾回收部分,重点介绍了标记-清除、复制算法、标记-整理等多种回收算法的工作原理及其适用场景,并通过实际案例分析了不同GC策略对应用性能的影响。对于开发者而言,理解这些原理有助于编写出更加高效、稳定的Java应用程序。 ####
|
21天前
|
安全 Java 程序员
Java内存模型的深入理解与实践
本文旨在深入探讨Java内存模型(JMM)的核心概念,包括原子性、可见性和有序性,并通过实例代码分析这些特性在实际编程中的应用。我们将从理论到实践,逐步揭示JMM在多线程编程中的重要性和复杂性,帮助读者构建更加健壮的并发程序。
|
18天前
|
存储 监控 算法
Java内存管理的艺术:深入理解垃圾回收机制####
本文将引领读者探索Java虚拟机(JVM)中垃圾回收的奥秘,解析其背后的算法原理,通过实例揭示调优策略,旨在提升Java开发者对内存管理能力的认知,优化应用程序性能。 ####
32 0
|
数据可视化 Java
java内存分析和线程分析----使用命令行或者可视化工具jvisualvm
java内存分析和线程分析----使用命令行或者可视化工具jvisualvm
162 0
|
1天前
|
安全 Java 编译器
深入理解Java中synchronized三种使用方式:助您写出线程安全的代码
`synchronized` 是 Java 中的关键字,用于实现线程同步,确保多个线程互斥访问共享资源。它通过内置的监视器锁机制,防止多个线程同时执行被 `synchronized` 修饰的方法或代码块。`synchronized` 可以修饰非静态方法、静态方法和代码块,分别锁定实例对象、类对象或指定的对象。其底层原理基于 JVM 的指令和对象的监视器,JDK 1.6 后引入了偏向锁、轻量级锁等优化措施,提高了性能。
11 3