jvm性能调优实战 - 30使用jmap和jhat摸清线上系统的对象分布

简介: jvm性能调优实战 - 30使用jmap和jhat摸清线上系统的对象分布

Pre

上一篇文章我们给大家介绍了一个平时工作中非常实用的工具,jstat。

用jstat就可以非常轻松便捷的了解到线上系统的运行状况,从新对象增速、Young GC触发频率以及耗时,再到对象进入老年代的增速以及Full GC触发频率以及耗时,可以完全摸清楚线上系统的JVM运行情况,为可能要做的优化做准备。

本文我们继续给大家介绍两个平时工作里非常实用的工具,jmap和jhat。

这两个工具可以帮助我们观察线上JVM中的对象分布,了解到你的系统平时运行过程中,到底哪些对象占据了主角位置,他们占据了多少内存空间,让你对你的系统运行有更加细致的了解。


使用jmap了解系统运行时的内存区域

其实如果单单只是要了解JVM的运行状况,然后去进行JVM GC优化,通常来说jstat就完全够用了

但是有的时候可能我们会发现JVM新增对象的速度很快,然后就想要去看看,到底什么对象占据了那么多的内存。

如果发现有的对象在代码中可以优化一下创建的时机,避免那种对象对内存占用过大,那么也许甚至可以去反过来优化一下代码。

当然,其实如果不是出现OOM那种极端情况,也并没有那么大的必要去着急优化代码。

但是这篇文章我们来学习一下如何了解线上系统jvm中的对象分布,也是有好处的,比如之前我们的案例中就发现年轻代里总是有500kb左右的未知对象,大家是不是会很好奇?如果可以看到jvm中这500kb的对象到底是什么就好了,所以学习一下这个技巧是有用的。

jmap -heap PID

先看一个命令:jmap -heap PID

这个命令可以打印出来一系列的信息,我们就不长篇大论的粘贴出来具体的信息了,因为内容篇幅太大了,其实也没太大意义,因为里面的东西大家自己看字面意思都能看懂的。我们就简单给大家说一下这里会打印出来什么东西。

大致来说,这个信息会打印出来堆内存相关的一些参数设置,然后就是当前堆内存里的一些基本各个区域的情况

比如Eden区总容量、已经使用的容量、剩余的空间容量,两个Survivor区的总容量、已经使用的容量和剩余的空间容量,老年代的总容量、已经使用的容量和剩余的容量。

但是这些信息大家会想了,其实jstat已经有了啊!对的,所以一般不会用jmap去看这些信息,毕竟他信息还没jstat全呢,因为没有gc相关的统计。


使用jmap了解系统运行时的对象分布

其实jmap命令比较有用的一个使用方式,是如下的:

jmap -histo PID

这个命令会打印出来类似下面的信息:

这个就很有意思了, 他会按照各种对象占用内存空间的大小降序排列,把占用内存最多的对象放在最上面。

所以如果你只是想要简单的了解一下当前jvm中的对象对内存占用的情况,只要直接用jmap -histo命令即可,非常好用

可以快速了解到当前内存里到底是哪个对象占用了大量的内存空间。


使用jmap生成堆内存转储快照

但是如果你仅仅只是看一个大概,感觉就只是看看上述那些对象占用内存的情况,感觉还不够,想要来点深入而且仔细点的

那就可以用jmap命令生成一个堆内存快照放到一个文件里去,用如下的命令即可:

jmap -dump:live,format=b,file=dump.hprof PID

这个命令会在当前目录下生成一个dump.hrpof文件,这里是二进制的格式,你不能直接打开看的,他把这一时刻JVM堆内存里所有对象的快照放到文件里去了,供你后续去分析。


使用jhat在浏览器中分析堆转出快照

接着就可以使用jhat去分析堆快照了,jhat内置了web服务器,他会支持你通过浏览器来以图形化的方式分析堆转储快照

使用如下命令即可启动jhat服务器,还可以指定自己想要的http端口号,默认是7000端口号:

jhat dump.hprof -port 7000

接着你就在浏览器上访问当前这台机器的7000端口号,就可以通过图形化的方式去分析堆内存里的对象分布情况了。


相关文章
|
4月前
|
监控 Java 测试技术
JVM 性能调优 及 为什么要减少 Full GC
JVM 性能调优 及 为什么要减少 Full GC
112 4
|
22天前
|
缓存 算法 Java
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
这篇文章详细介绍了Java虚拟机(JVM)中的垃圾回收机制,包括垃圾的定义、垃圾回收算法、堆内存的逻辑分区、对象的内存分配和回收过程,以及不同垃圾回收器的工作原理和参数设置。
45 4
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
|
22天前
|
存储 Java
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配
这篇文章详细地介绍了Java对象的创建过程、内存布局、对象头的MarkWord、对象的定位方式以及对象的分配策略,并深入探讨了happens-before原则以确保多线程环境下的正确同步。
43 0
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配
|
24天前
|
算法 Java
JVM进阶调优系列(3)堆内存的对象什么时候被回收?
堆对象的生命周期是咋样的?什么时候被回收,回收前又如何流转?具体又是被如何回收?今天重点讲对象GC,看完这篇就全都明白了。
|
4月前
|
存储 监控 算法
(六)JVM成神路之GC基础篇:对象存活判定算法、GC算法、STW、GC种类详解
经过前面五个章节的分析后,对于JVM的大部分子系统都已阐述完毕,在本文中则开始对JVM的GC子系统进行全面阐述,GC机制也是JVM的重中之重,调优、监控、面试都逃不开的JVM话题。
113 8
|
4月前
|
存储 缓存 算法
(五)JVM成神路之对象内存布局、分配过程、从生至死历程、强弱软虚引用全面剖析
在上篇文章中曾详细谈到了JVM的内存区域,其中也曾提及了:Java程序运行过程中,绝大部分创建的对象都会被分配在堆空间内。而本篇文章则会站在对象实例的角度,阐述一个Java对象从生到死的历程、Java对象在内存中的布局以及对象引用类型。
118 8
|
4月前
|
JSON Java BI
一次Java性能调优实践【代码+JVM 性能提升70%】
这是我第一次对系统进行调优,涉及代码和JVM层面的调优。如果你能看到最后的话,或许会对你日常的开发有帮助,可以避免像我一样,犯一些低级别的错误。本次调优的代码是埋点系统中的报表分析功能,小公司,开发结束后,没有Code Review环节,所以下面某些问题,也许在Code Review环节就可以避免。
158 0
一次Java性能调优实践【代码+JVM 性能提升70%】
|
22天前
|
存储 安全 Java
jvm 锁的 膨胀过程?锁内存怎么变化的
【10月更文挑战第3天】在Java虚拟机(JVM)中,`synchronized`关键字用于实现同步,确保多个线程在访问共享资源时的一致性和线程安全。JVM对`synchronized`进行了优化,以适应不同的竞争场景,这种优化主要体现在锁的膨胀过程,即从偏向锁到轻量级锁,再到重量级锁的转变。下面我们将详细介绍这一过程以及锁在内存中的变化。
33 4
|
3月前
|
Java Docker 索引
记录一次索引未建立、继而引发一系列的问题、包含索引创建失败、虚拟机中JVM虚拟机内存满的情况
这篇文章记录了作者在分布式微服务项目中遇到的一系列问题,起因是商品服务检索接口测试失败,原因是Elasticsearch索引未找到。文章详细描述了解决过程中遇到的几个关键问题:分词器的安装、Elasticsearch内存溢出的处理,以及最终成功创建`gulimall_product`索引的步骤。作者还分享了使用Postman测试接口的经历,并强调了问题解决过程中遇到的挑战和所花费的时间。
|
25天前
|
存储 缓存 算法
JVM核心知识点整理(内存模型),收藏再看!
JVM核心知识点整理(内存模型),收藏再看!
JVM核心知识点整理(内存模型),收藏再看!