Java命令:jmap — 打印指定进程的共享对象内存映射或堆内存细节

文章目录

    • 一、前言
    • 二、命令介绍
    • 三、使用实例
      • 1、jmap -heap [pid]
      • 2、jmap -histo[:live] [pid]
      • 3、jmap -histo[:live] [pid] |grep "[关键字1]\|[关键字2]"
      • 4、jmap -dump:live,format=b,file=a.log [pid]
    • 四、总结

一、前言

jdk安装后会自带一些小工具,jmap命令(Java Memory Map)是其中之一。主要用于打印指定Java进程(或核心文件、远程调试服务器)的共享对象内存映射或堆内存细节。

jmap 命令可以获得运行中的jvm的堆的快照,从而可以离线分析堆,以检查内存泄漏,检查一些严重影响性能的大对象的创建,检查系统中什么对象最多,各种对象所占内存的大小等等。可以使用jmap生成Heap Dump。

java memory = direct memory(直接内存) + jvm memory(MaxPermSize +Xmx)

1)直接内存跟堆

直接内存 则是一块由程序本身管理的一块内存空间,它的效率要比标准内存池要高,主要用于存放网络通信时数据缓冲和磁盘数据交换时的数据缓冲。

DirectMemory 容量可以通过 -XX:MaxDirectMemorySize 指定,如果不指定,则默认为与Java堆的最大值(-Xmx指定)一样。但是,在OSX上的最新版本的 JVM,对直接内存的默认大小进行修订,改为“在不指定直接内存大小的时默认分配的直接内存大小为64MB”,可以通过 -XX:MaxMemorySize 来显示指定直接内存的大小。

2)堆(Heap)和非堆(Non-heap)内存

按照官方的说法:“Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配。堆是在 Java 虚拟机启动时创建的。”“在JVM中堆之外的内存称为非堆内存(Non-heap memory)”。

可以看出JVM主要管理两种类型的内存:堆和非堆

  • 就是Java代码可及的内存,是留给开发人员使用的;
  • 非堆 就是JVM留给自己用的。

所以方法区、JVM内部处理或优化所需的内存(如JIT编译后的代码缓存)、每个类结构(如运行时常数池、字段和方法数据)以及方法和构造方法的代码都在非堆内存中。

3)栈与堆

栈解决程序的运行问题,即程序如何执行,或者说如何处理数据;堆解决的是数据存储的问题,即数据怎么放、放在哪儿。

在Java中一个线程就会相应有一个线程栈与之对应,这点很容易理解,因为不同的线程执行逻辑有所不同,因此需要一个独立的线程栈。而堆则是所有线程共享的。栈因为是运行单位,因此里面存储的信息都是跟当前线程(或程序)相关信息的。包括局部变量、程序运行状态、方法返回值等等;而堆只负责存储对象信息。

Java的堆是一个运行时数据区,类的(对象从中分配空间。这些对象通过new、newarray、anewarray和multianewarray等 指令建立,它们不需要程序代码来显式的释放。堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时 动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。 栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。栈中主要存放一些基本类 型的变量(,int, short, long, byte, float, double, boolean, char)和对象句柄。

线程占用大小在MaxPermSize中进行内存申请和分配。


二、命令介绍

Usage:jmap [option] <pid>(to connect to running process)jmap [option] <executable <core>(to connect to a core file)jmap [option] [server_id@]<remote server IP or hostname>(to connect to remote debug server)where <option> is one of:<none>               to print same info as Solaris pmap-heap                to print java heap summary-histo[:live]        to print histogram of java object heap; if the "live"suboption is specified, only count live objects-clstats             to print class loader statistics-finalizerinfo       to print information on objects awaiting finalization-dump:<dump-options> to dump java heap in hprof binary formatdump-options:live         dump only live objects; if not specified,all objects in the heap are dumped.format=b     binary formatfile=<file>  dump heap to <file>Example: jmap -dump:live,format=b,file=heap.bin <pid>-F                   force. Use with -dump:<dump-options> <pid> or -histoto force a heap dump or histogram when <pid> does notrespond. The "live" suboption is not supportedin this mode.-h | -help           to print this help message-J<flag>             to pass <flag> directly to the runtime system

注:

  • -heap:打印jvm heap的情况
  • -histo:打印jvm heap的直方图。其输出信息包括类名,对象数量,对象占用大小。
  • -histo:live :同上,但是只答应存活对象的情况
  • -permstat:打印permanent generation heap情况

三、使用实例

1、jmap -heap [pid]

展示pid的整体堆信息。

首先启动一个tomcat,然后使用如下命令获取tomcat的进程ID。

ps -ef|grep tomcat

在这里插入图片描述
然后执行:

jmap -heap 86038

输出内容:

Attaching to process ID 86038, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.121-b13using thread-local object allocation.
Parallel GC with 4 thread(s)Heap Configuration:         # 堆内存初始化配置MinHeapFreeRatio         = 0                        # -XX:MinHeapFreeRatio设置JVM堆最小空闲比率  MaxHeapFreeRatio         = 100                      # -XX:MaxHeapFreeRatio设置JVM堆最大空闲比率  MaxHeapSize              = 2147483648 (2048.0MB)    # -XX:MaxHeapSize=设置JVM堆的最大大小NewSize                  = 44564480 (42.5MB)        # -XX:NewSize=设置JVM堆的‘新生代’的默认大小MaxNewSize               = 715653120 (682.5MB)      # -XX:MaxNewSize=设置JVM堆的‘新生代’的最大大小OldSize                  = 89653248 (85.5MB)        # -XX:OldSize=设置JVM堆的‘老生代’的大小NewRatio                 = 2                        # -XX:NewRatio=:‘新生代’和‘老生代’的大小比率SurvivorRatio            = 8                        # -XX:SurvivorRatio=设置年轻代中Eden区与Survivor区的大小比值MetaspaceSize            = 21807104 (20.796875MB)   CompressedClassSpaceSize = 1073741824 (1024.0MB)    MaxMetaspaceSize         = 17592186044415 MB        G1HeapRegionSize         = 0 (0.0MB)Heap Usage:
PS Young Generation
Eden Space:           # Eden区内存分布capacity = 426770432 (407.0MB)used     = 79056192 (75.39385986328125MB)free     = 347714240 (331.60614013671875MB)18.524289892698096% used
From Space:           # 其中一个Survivor区的内存分布capacity = 30932992 (29.5MB)used     = 0 (0.0MB)free     = 30932992 (29.5MB)0.0% used
To Space:             # 另一个Survivor区的内存分布capacity = 31457280 (30.0MB)used     = 0 (0.0MB)free     = 31457280 (30.0MB)0.0% used
PS Old Generationcapacity = 72351744 (69.0MB)used     = 21741336 (20.734153747558594MB)free     = 50610408 (48.265846252441406MB)30.049498184867527% used16180 interned Strings occupying 2074344 bytes.

2、jmap -histo[:live] [pid]

展示class的内存情况。

jmap -histo 86038

执行结果:

 num     #instances         #bytes  class name
----------------------------------------------1:          7287       46167552  [I2:         78166       33933008  [B3:        221419       25746168  [C4:        116110        2786640  java.lang.String5:         11708         886224  [Ljava.lang.Object;6:         18869         603808  java.util.HashMap$Node7:         24275         582600  java.lang.StringBuilder8:          6464         568832  java.lang.reflect.Method9:          4715         541352  java.lang.Class10:          4847         418760  [S11:          1686         391288  [Ljava.util.HashMap$Node;...

注:

  • instances:实例数;
  • bytes:内存占用大小;
  • classs name:类名。

它基本是按照使用使用大小逆序排列的。

jmap -histo:live 86038

获取所有生存的对象的内存情况。

注:

  • 该命令获取的结果与jmap -histo [pid]获取结果一致;
  • 执行jmap -histo:live [pid]时,JVM会先触发gc,然后再统计信息

从打印结果可看出,类名中存在[C、[B等内容,只知道它占用了那么大的内存,但不知道由什么对象创建的。下一步需要将其他dump出来,使用内存分析工具进一步明确它是由谁引用的、由什么对象。

另外可以执行如下命令将打印内容保存到文件中。

jmap -histo:live 86038>a.log

通过对多次打印内容的对比,可以对比出GC回收了哪些对象。


3、jmap -histo[:live] [pid] |grep “[关键字1]|[关键字2]”

展示指定关键字的类的内存情况。

jmap -histo:live 86038 | grep "java.util.\|java.lang."

执行结果:

 num     #instances         #bytes  class name
----------------------------------------------6:         18869         603808  java.util.HashMap$Node7:         24275         582600  java.lang.StringBuilder8:          6464         568832  java.lang.reflect.Method9:          4715         541352  java.lang.Class...

从执行结果看,打印出了类全路径名称中包含 java.util.java.lang. 的所有类内存情况。

注:匹配多个关键字之间用 \| 隔开。


4、jmap -dump:live,format=b,file=a.log [pid]

内存信息dump到a.log文件中。

这个命令执行,JVM会将整个heap的信息dump写入到一个文件,heap如果比较大的话,就会导致这个过程比较耗时,并且执行的过程中为了保证dump的信息是可靠的,所以会暂停应用

该命令通常用来分析内存泄漏OOM,通常做法是:

1)首先配置JVM启动参数,让JVM在遇到OutOfMemoryError时自动生成Dump文件

-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path

2)然后使用命令

// 如果只dump heap中的存活对象,则加上选项-live。
jmap -dump:format=b,file=/path/heap.bin [pid]

四、总结

  • 1、如果程序内存不足或者频繁GC,很有可能存在内存泄露情况,这时候就要借助Java堆Dump查看对象的情况。

  • 2、要制作堆Dump可以直接使用jvm自带的jmap命令

  • 3、可以先使用jmap -heap命令查看堆的使用情况,看一下各个堆空间的占用情况。

  • 4、使用jmap -histo:[live]查看堆内存中的对象的情况。如果有大量对象在持续被引用,并没有被释放掉,那就产生了内存泄露,就要结合代码,把不用的对象释放掉。

  • 5、也可以使用 jmap -dump:format=b,file=命令将堆信息保存到一个文件中,再借助jhat命令查看详细内容

  • 6、在内存出现泄露、溢出或者其它前提条件下,建议多dump几次内存,把内存文件进行编号归档,便于后续内存整理分析。

  • 7、在用cms gc的情况下,执行jmap -heap有些时候会导致进程变T,因此强烈建议别执行这个命令,如果想获取内存目前每个区域的使用状况,可通过jstat -gc或jstat -gccapacity来拿到。

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

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

相关文章

概率论 一维随机变量

随机变量 离散型随机变量:有限个或无限可列个 连续型随机变量 分布函数F(X) 范围是[a,b) 包含能取到a以及a之前的值的概率相加 分布律(概率分布) 1.所有概率相加为1 2.WX-1,计算出每一个对应的W,然后如果有相同的W就合并其概率,最后一一对应P(x)即可 概率密度函数(密度) …

JAVA牛客专项练习2020.12.31

1.使用迭代器的remove方法&#xff0c;可以边遍历边删除元素 2.线程 启动线程 new thread&#xff08;&#xff09;.start&#xff08;&#xff09; new thread&#xff08;new runnable&#xff08;&#xff09;&#xff09;.start&#xff08;&#xff09; 普通方法&#xf…

安卓牛客专项练习2020.12.31

1.窗口dialog或半透明 2.Pracelable性能比serializable高

安卓系统体系架构

1.大体:共有四层&#xff0c;系统应用层&#xff0c;JAVA API层&#xff0c;安卓系统运行层&#xff0c;Linux内核层 具体: 系统应用层&#xff08;System Apps&#xff09; Java API 框架层&#xff08;Java API Framework&#xff09; Android系统运行层&#xff08;包括Andr…

Java命令:jstack — 获取线程dump信息

目录一、命令介绍二、使用实例实例一&#xff1a;jstack查看输出实例二&#xff1a;jstack统计线程数实例三&#xff1a;jstack检测死锁实例四&#xff1a;jstack检测CPU高一、命令介绍 Usage:jstack [-l] <pid>(to connect to running process) //连接活动线程jstack …

Java多线程死锁例子

目录一、产生死锁的原因二、如何避免死锁一、产生死锁的原因 发生死锁的情况&#xff1a; 多个线程需要同时占用多个共享资源而发生需要互相死循环等待的情况&#xff0c;就是&#xff0c;两个线程互相等待着对象释放锁&#xff0c;一直这样僵持下去&#xff0c;所以导致了死锁…

安卓四大组件简介

安卓四大组件 Activity活动&#xff0c;Service服务&#xff0c;BroadcastRecevicer广播接受器&#xff0c;Content Provider内容提供者 Activity活动 所有程序的流程都运行在activity中 Service服务 只能后台运行&#xff0c;没有界面的长生命周期的代码 BroadcastRece…

WebLogic域的创建与发布

目录一、前言二、准备三、创建域步骤第一步&#xff1a;直接【回车】第二步&#xff1a;直接【回车】第三步&#xff1a;直接【回车】第四步&#xff1a;输入域名称后【回车】第五步&#xff1a;直接【回车】第六步&#xff1a;直接【回车】&#xff08;此步骤是提示域的存放目…

WebLogic启动失败:java.lang.AssertionError: Could not obtain the localhost address.

目录一、错误信息二、解决方案第一步&#xff1a;查看本机计算机名称第二步&#xff1a;编辑hosts文件一、错误信息 linux下启动WebLogic报如下错误&#xff1a; 二、解决方案 此错误多半是hosts文件不对导致的。 解决步骤如下&#xff1a; 第一步&#xff1a;查看本机计…

Windows查找JDK的路径

第一步&#xff1a;确定是否安装JDK 在控制台输入&#xff1a; java -version输出结果&#xff1a; 此时说明你电脑安装了JDK。 第二步&#xff1a;查找路径 然后在控制台输入&#xff1a; java -verbose输出结果&#xff1a; 从最后的jre目录可以找到相应的jdk目录。 …

安卓布局中xml文件属性和ID简介

编写xml属性 加载xml资源 当编译应用时&#xff0c;系统会将每个xml文件编译为view资源 属性 xml属性&#xff1a;特有属性&#xff0c;共有属性&#xff0c;其他属性&#xff08;布局参数&#xff09; ID ——在结构树中对view对象唯一标识 编译应用后&#xff0c;系统以…

Java监控工具VisualVM

目录一、简介二、内存分析1、Heap堆三、CPU分析四、线程分析一、简介 VisualVM 是一款免费的&#xff0c;集成了多个JDK命令行工具的可视化工具&#xff0c;它能为您提供强大的分析能力&#xff0c;对Java应用程序做 性能分析和调优 。这些功能包括 生成和分析海量数据、跟踪内…

C++数据类型

C 数据类型 |–基本数据类型: 整型 short短整型 2 int基本整型4 long长整型 8 浮点型 float单精度型 4 double双精度型 8 long double长双精度型 16 字符型 char 1 逻辑型 bool 1 空类型 void |–构造类型 数组类型 构造体类型 struct 共用体类型 union 枚举类型 enum 类类型…

Android Gradle 多渠道打包、动态配置AppName

目录一、简介二、Gradle多渠道打包1、普通做法2、Gradle多渠道打包一、简介 因为国内Android应用分发市场的现状&#xff0c;我们在发布APP时&#xff0c;一般需要生成多个渠道包&#xff0c;上传到不同的应用市场。这些渠道包需要包含不同的渠道信息&#xff0c;在APP和后台交…

Android Gradle 批量修改生成的apk文件名

目录一、简介二、代码实现1、 Gradle 3.0以下版本2、Gradle 3.0以上版本一、简介 平时开发都知道&#xff0c;我们要上线的时候需要在Android studio打包apk文件&#xff0c;可是默认的打包名是app-release.apk或者app-debug.apk这样的名字&#xff0c;太没有辨识度了。 下面…

Android Studio 代理设置以及代理完全清除

目录一、代理设置二、代理完全清除一、代理设置 首先我们来看下怎样设置代理&#xff0c;Mac下打开【Preferences…】&#xff0c;然后搜索"HTTP"&#xff0c;选择【HTTP Proxy】&#xff0c;按图中设置配置好后&#xff0c;点击【Apply】&#xff0c;然后在点击【O…

安卓布局位置,dp与px的区别

手机6寸—指对角线 布局位置 横轴—x轴 纵轴—y轴 一个像素点 dp与Px dp:设备无关像素,与像素密度相关,像素距离 dpi:像素密度,每英寸包含的像素数 px:屏幕上一个物理像素点 ldpi低密度 1dp0.75px mdpi中密度 1dp1px hdpi高密度 1dp1.5px xhdpi超高密度 1dp2px xxhdpi超…

Android程序结构

Project方式 .gradle文件夹:编译相关生成 .idea文件夹:idea生成 app文件夹----应用程序的源代码和资源 build----编译后的文件存放的位置,最终apk文件存放的位置 libs:存放.jar和.so文件 src:AndroidTest与test存放测试相关的内容 main中Java文件夹存放Java源码,res文件…

通过Github创建Android库供其他项目依赖引用

目录一、简介二、实现第一步&#xff1a;将自己的项目托管到Github上。第二步&#xff1a;点击releases。第三步&#xff1a;创建release。第四步&#xff1a;填写版本号、名称、描述信息。第五步&#xff1a;点击【Publish release】。第六步&#xff1a;复制项目路径。第七步…