JMap

首先要知道Java进程的pid。

Windows:

..

..

..

Linux:

ps -ef | grep java

查看堆栈信息(jmap -heap pid)

jmap -heap
Attaching to process ID , please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.161-b12 using thread-local object allocation.
Parallel GC with thread(s) Heap Configuration:
MinHeapFreeRatio =
MaxHeapFreeRatio =
MaxHeapSize = (.0MB)
NewSize = (.5MB)
MaxNewSize = (.5MB)
OldSize = (.5MB)
NewRatio =
SurvivorRatio =
MetaspaceSize = (.796875MB)
CompressedClassSpaceSize = (.0MB)
MaxMetaspaceSize = MB
G1HeapRegionSize = (.0MB) Heap Usage:
PS Young Generation
Eden Space:
capacity = (.0MB)
used = (.410011291503906MB)
free = (.589988708496094MB)
83.70770967923679% used
From Space:
capacity = (.0MB)
used = (.9687957763671875MB)
free = (.0312042236328125MB)
59.37591552734375% used
To Space:
capacity = (.5MB)
used = (.0MB)
free = (.5MB)
0.0% used
PS Old Generation
capacity = (.5MB)
used = (.046875MB)
free = (.453125MB)
0.05482456140350877% used interned Strings occupying bytes.

打印等待回收的对象信息(jmap -finalizerinfo pid)

jmap -finalizerinfo
Attaching to process ID , please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.161-b12
Number of objects pending for finalization:

打印堆里面对象的统计信息:对象数量、占用大小、类名(jmap -histo:live pid | more)

jmap -histo:live  | more

 num     #instances         #bytes  class name
----------------------------------------------
: [C
: [B
: java.lang.String
: java.lang.Class
: org.apache.zookeeper.data.StatPersisted
: [Ljava.lang.Object;
: java.util.HashMap$Node
: java.util.concurrent.ConcurrentHashMap$Node
: java.util.HashMap
: [I
: [Ljava.util.HashMap$Node;
: org.apache.zookeeper.server.DataNode
: java.lang.reflect.Method
: org.apache.zookeeper.server.Request
: java.util.TreeMap$Entry
: org.apache.zookeeper.txn.TxnHeader
: java.util.LinkedList$Node
: [Ljava.lang.String;
: java.util.HashSet
: org.apache.zookeeper.server.quorum.QuorumPacket
: java.lang.ref.SoftReference
: [Ljava.util.concurrent.ConcurrentHashMap$Node;

打印类加载器统计信息(jmap -clstats pid)

jmap -clstats
Attaching to process ID , please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.161-b12
finding class loader instances ..done.
computing per loader stat ..done.
please wait.. computing liveness....................................liveness analysis may be inaccurate ...
class_loader classes bytes parent_loader alive? type <bootstrap> null live <internal>
0x000000008128cef8 null dead sun/reflect/DelegatingClassLoader@0x0000000017289df8
0x000000008128d088 null dead sun/reflect/DelegatingClassLoader@0x0000000017289df8
0x000000008128d218 null dead sun/reflect/DelegatingClassLoader@0x0000000017289df8
0x00000000814621d0 0x000000008120b6c8 dead java/util/ResourceBundle$RBClassLoader@0x0000000017303798
0x000000008120b6c8 0x000000008120b728 live sun/misc/Launcher$AppClassLoader@0x000000001728f6a0
0x000000008120b728 null live sun/misc/Launcher$ExtClassLoader@0x000000001728fa48
0x000000008128cfc0 null dead sun/reflect/DelegatingClassLoader@0x0000000017289df8
0x000000008128d150 null dead sun/reflect/DelegatingClassLoader@0x0000000017289df8 total = N/A alive=, dead= N/A

把堆信息生成一个文件(jmap -dump:live,format=b,file=heap.bin <pid>)

[d:\]$ jmap -dump:live,format=b,file=heap.bin
Dumping heap to D:\heap.bin ...
Heap dump file created

之后,我们利用Mat来分析,下载 Eclipse Memory Analyzer

..

下载完解压

...

..

..

..打开我们刚才生成的文件

..

..看效果

..

JStat

每隔一段时间输出GC情况(jstat -gcutil pid inteval)

[d:\]$ jstat -gcutil
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0.00 0.00 0.94 7.26 96.88 93.14 0.061 0.022 0.082
0.00 0.00 0.94 7.26 96.88 93.14 0.061 0.022 0.082
0.00 0.00 0.94 7.26 96.88 93.14 0.061 0.022 0.082
0.00 0.00 0.94 7.26 96.88 93.14 0.061 0.022 0.082
0.00 0.00 0.94 7.26 96.88 93.14 0.061 0.022 0.082
0.00 0.00 0.94 7.26 96.88 93.14 0.061 0.022 0.082
0.00 0.00 0.94 7.26 96.88 93.14 0.061 0.022 0.082
0.00 0.00 0.94 7.26 96.88 93.14 0.061 0.022 0.082
0.00 0.00 0.94 7.26 96.88 93.14 0.061 0.022 0.082
0.00 0.00 0.94 7.26 96.88 93.14 0.061 0.022 0.082
0.00 0.00 0.94 7.26 96.88 93.14 0.061 0.022 0.082
0.00 0.00 0.94 7.26 96.88 93.14 0.061 0.022 0.082
0.00 0.00 0.94 7.26 96.88 93.14 0.061 0.022 0.082
0.00 0.00 0.94 7.26 96.88 93.14 0.061 0.022 0.082
0.00 0.00 0.94 7.26 96.88 93.14 0.061 0.022 0.082
0.00 0.00 0.94 7.26 96.88 93.14 0.061 0.022 0.082

参数:

S0        from区已使用容量的百分比
S1 to区已使用容量的百分比
E 伊甸区已使用容量的百分比
O 老年代已使用容量的百分比
M 元数据空间利用率
CCS 压缩类空间利用率
YGC 从应用程序启动到采样时年轻代中gc次数
YGCT 从应用程序启动到采样时年轻代中gc所用时间(s)
FGC 从应用程序启动到采样时old代(全gc)gc次数
FGCT 从应用程序启动到采样时old代(全gc)gc所用时间(s)
GCT 从应用程序启动到采样时gc用的总时间(s)

还有另外一个方法,输出的要全面一些

[d:\]$ jstat -gc
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
4096.0 3584.0 0.0 0.0 133120.0 1257.0 37376.0 2715.3 9600.0 9300.8 1152.0 1073.0 0.061 0.022 0.082
4096.0 3584.0 0.0 0.0 133120.0 1257.0 37376.0 2715.3 9600.0 9300.8 1152.0 1073.0 0.061 0.022 0.082
4096.0 3584.0 0.0 0.0 133120.0 1257.0 37376.0 2715.3 9600.0 9300.8 1152.0 1073.0 0.061 0.022 0.082
4096.0 3584.0 0.0 0.0 133120.0 1257.0 37376.0 2715.3 9600.0 9300.8 1152.0 1073.0 0.061 0.022 0.082

参数:

S0C:   当前from区容量
S1C:   当前to区容量
S0U:   from区已使用的容量
S1U:   to区已使用的容量
EC:    当前伊甸区的容量
EU:   伊甸区已使用的容量
OC:   老年代的容量
OU:   老年代已使用的容量
MC:   元空间容量
MU:   元空间已使用容量
CCSC: 压缩类空间容量
CCSU: 已使用的压缩类空间
YGC:   年轻代gc次数
YGCT: 年轻代gc时间
FGC:   full gc 次数
FGCT:  Full gc时间
GCT:   总gc时间

场景:Full GC时间很长,并且GC之前堆内存是稳步上升的

要么是内存泄漏,要么是垃圾回收出了问题。

第一步你要看一下堆里对象是否异常

jmap -histo:live 【pid】 | more

然后看一下GC情况是否出现了异常的回收时间

jstat -gc 【pid】【interval】

再看一下内存分配是否出现了问题

jmap -heap 【pid】

关于GC,对于CMS和G1是有区别的。

G1收集器处理Eden区是根据智能算法分配内存的。比如第一次回收发现年轻代只有200M,不够用,便设置成800M;第二次回收虽然年轻代有800M,但是仍然不够用,便再次增加比如1800M...之后发现1800M足够满足要求了,便将年轻代大小控制在这个值。

CMS则不负责年轻代大小的自适应,如果你设置小了,在极端情况就会出现漫长的Full GC。

设置新生代大小:-xmn1500m

GC日志

你可以在启动参数里加上 -XX:+PrintGCDetails 这样在发生GC就会打印日志

然后利用 ps -ef | grep java 查看

测试一下的话,在IDEA里的Edit Configurations设置

先确定一下你目前的配置(我的年轻代只有42.5MB)

jmap -heap

Attaching to process ID , please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.161-b12 using thread-local object allocation.
Parallel GC with thread(s) Heap Configuration:
MinHeapFreeRatio =
MaxHeapFreeRatio =
MaxHeapSize = (.0MB)
NewSize = (.5MB)
MaxNewSize = (.5MB)
OldSize = (.5MB)
NewRatio =
SurvivorRatio =
MetaspaceSize = (.796875MB)
CompressedClassSpaceSize = (.0MB)
MaxMetaspaceSize = MB
G1HeapRegionSize = (.0MB) Heap Usage:
PS Young Generation
Eden Space:
capacity = (.0MB)
used = (.41856384277344MB)
free = (.58143615722656MB)
85.0804930466872% used
From Space:
capacity = (.5MB)
used = (.96875MB)
free = (.53125MB)
21.52777777777778% used
To Space:
capacity = (.5MB)
used = (.0MB)
free = (.5MB)
0.0% used
PS Old Generation
capacity = (.5MB)
used = (.8634796142578125MB)
free = (.63652038574219MB)
3.349098964044225% used interned Strings occupying bytes.

查看用的什么收集器(目前不是G1收集器)

java -XX:+PrintCommandLineFlags -version
-XX:InitialHeapSize= -XX:MaxHeapSize= -XX:+PrintCommandLineFl
ags -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesInd
ividualAllocation -XX:+UseParallelGC
java version "1.8.0_161"
Java(TM) SE Runtime Environment (build 1.8.0_161-b12)
Java HotSpot(TM) -Bit Server VM (build 25.161-b12, mixed mode)

测试

public static void main(String[] args) throws Exception {
List<Integer> list = new ArrayList<>();
for (int i = 0; i < 10000000; i++){
list.add(i);
} Thread.sleep(10000);
System.out.println("==================Exit==================");
}

输出:(发生了好多次GC)

[GC (Allocation Failure) [PSYoungGen: 33280K->5100K(38400K)] 33280K->20309K(125952K), 0.0287241 secs] [Times: user=0.08 sys=0.00, real=0.03 secs]
[GC (Allocation Failure) [PSYoungGen: 38380K->5109K(71680K)] 53589K->41777K(159232K), 0.0325626 secs] [Times: user=0.13 sys=0.00, real=0.03 secs]
[GC (Allocation Failure) [PSYoungGen: 56608K->5093K(71680K)] 93276K->92393K(159232K), 0.0835488 secs] [Times: user=0.36 sys=0.00, real=0.08 secs]
[Full GC (Ergonomics) [PSYoungGen: 5093K->0K(71680K)] [ParOldGen: 87300K->81512K(194560K)] 92393K->81512K(266240K), [Metaspace: 3484K->3484K(1056768K)], 1.2747203 secs] [Times: user=4.23 sys=0.03, real=1.28 secs]
[GC (Allocation Failure) [PSYoungGen: 66560K->5120K(103936K)] 184127K->158535K(298496K), 0.2367500 secs] [Times: user=0.97 sys=0.00, real=0.24 secs]
[Full GC (Ergonomics) [PSYoungGen: 5120K->0K(103936K)] [ParOldGen: 153415K->142402K(306176K)] 158535K->142402K(410112K), [Metaspace: 3987K->3987K(1056768K)], 1.2205739 secs] [Times: user=5.96 sys=0.00, real=1.22 secs]
[GC (Allocation Failure) [PSYoungGen: 98816K->5120K(138240K)] 241218K->239348K(444416K), 0.1228611 secs] [Times: user=0.48 sys=0.02, real=0.12 secs]
[Full GC (Ergonomics) [PSYoungGen: 5120K->0K(138240K)] [ParOldGen: 234228K->202870K(459776K)] 239348K->202870K(598016K), [Metaspace: 3988K->3988K(1056768K)], 1.8345978 secs] [Times: user=9.27 sys=0.00, real=1.84 secs]
==================Exit==================
Heap
PSYoungGen total 138240K, used 11827K [0x00000000d5b80000, 0x00000000e9b00000, 0x0000000100000000)
eden space 133120K, 8% used [0x00000000d5b80000,0x00000000d670cf70,0x00000000ddd80000)
from space 5120K, 0% used [0x00000000ddd80000,0x00000000ddd80000,0x00000000de280000)
to space 95232K, 0% used [0x00000000e3e00000,0x00000000e3e00000,0x00000000e9b00000)
ParOldGen total 459776K, used 202870K [0x0000000081200000, 0x000000009d300000, 0x00000000d5b80000)
object space 459776K, 44% used [0x0000000081200000,0x000000008d81d8a0,0x000000009d300000)
Metaspace used 3995K, capacity 4568K, committed 4864K, reserved 1056768K
class space used 435K, capacity 460K, committed 512K, reserved 1048576K

换成G1试试

再次运行一遍上面代码

[GC pause (G1 Evacuation Pause) (young), 0.0435845 secs]
[Eden: 20.0M(20.0M)->.0B(.0K) Survivors: .0B->.0K Heap: 32.7M(128.0M)->28.8M(128.0M)]
...
[GC pause (G1 Evacuation Pause) (young), 0.0299648 secs]
[Eden: .0K(.0K)->.0B(11.0M) Survivors: .0K->.0K Heap: 31.8M(128.0M)->34.7M(256.0M)]
...
[GC pause (G1 Evacuation Pause) (young), 0.0356263 secs]
[Eden: 11.0M(11.0M)->.0B(23.0M) Survivors: .0K->.0K Heap: 63.1M(256.0M)->64.6M(512.0M)]
...
[GC pause (G1 Evacuation Pause) (young), 0.0447098 secs]
[Eden: 23.0M(23.0M)->.0B(36.0M) Survivors: .0K->.0K Heap: 103.2M(512.0M)->105.2M(816.0M)]
...
[GC pause (G1 Evacuation Pause) (young), 0.0506044 secs]
[Eden: 36.0M(36.0M)->.0B(47.0M) Survivors: .0K->.0K Heap: 164.7M(816.0M)->167.7M(1059.0M)]
...
[GC pause (G1 Evacuation Pause) (young), 0.0679058 secs]
[Eden: 47.0M(47.0M)->.0B(55.0M) Survivors: .0K->.0K Heap: 249.9M(1059.0M)->251.4M(1254.0M)] ==================Exit==================
Heap
garbage-first heap total 1284096K, used 330981K [0x0000000081200000, 0x0000000081302730, 0x0000000100000000)
region size 1024K, young (27648K), survivors (7168K)
Metaspace used 3995K, capacity 4568K, committed 4864K, reserved 1056768K
class space used 435K, capacity 460K, committed 512K, reserved 1048576K

其中省略了无关代码,可以发现G1收集器可以优化Eden区的大小。

-XX:+PrintGCDetails 输出GC的详细日志
-XX:+PrintGCDateStamps 输出GC的时间
-XX:+PrintHeapAtGC GC的前后打印出堆的信息
-Xloggc:../logs/gc.log 日志文件的输出路径

参考:https://docs.oracle.com/javase/8/docs/technotes/tools/windows/jstat.html

JVM调优工具的更多相关文章

  1. 《深入理解Java虚拟机》(五)JVM调优 - 工具

    JVM调优 - 工具 JConsole:Java监视与管理控制台 JConsole是一个机遇JMX(Java Management Extensions,即Java管理扩展)的JVM监控与管理工具,监 ...

  2. JVM调优-工具篇

    原文地址 16年的时候花了一些时间整理了一些关于jvm的介绍文章,到现在回顾起来还是一些还没有补充全面,其中就包括如何利用工具来监控调优前后的性能变化.工具做为图形化界面来展示更能直观的发现问题,另一 ...

  3. jvm系列(七):jvm调优-工具篇

    16年的时候花了一些时间整理了一些关于jvm的介绍文章,到现在回顾起来还是一些还没有补充全面,其中就包括如何利用工具来监控调优前后的性能变化.工具做为图形化界面来展示更能直观的发现问题,另一方面一些耗 ...

  4. Java虚拟机(六):JVM调优工具

    工具做为图形化界面来展示更能直观的发现问题,另一方面一些耗费性能的分析(dump文件分析)一般也不会在生产直接分析,往往dump下来的文件达1G左右,人工分析效率较低,因此利用工具来分析jvm相关问题 ...

  5. jvm系列(六):jvm调优-工具篇

    ## jdk自带的工具### jconsole Jconsole(Java Monitoring and Management Console)是从java5开始,在JDK中自带的java监控和管理控 ...

  6. 18.jvm调优工具及案例分析

    目标: Jmap.Jstack.Jinfo详解 JvisualVm调优工具实战 JVM内存或CPU飙高如何定位 JState命令预估JVM运行情况 系统频繁Full GC导致系统卡顿实战调优 内存泄漏 ...

  7. JVM调优工具锦囊

    Arthas线上 分析诊断调优工具 以前我们要排查线上问题,通常使用的是jdk自带的调优工具和命令.最常见的就是dump线上日志,然后下载到本地,导入到jvisualvm工具中.这样操作有诸多不变,现 ...

  8. JVM调优工具使用手册

    ​ 作为Java开发人员,我们肯定知道JDK的bin目录下有"java.exe"."javac.exe"这两个命令工具,这也是我们平时用得最多的工具.但其实bi ...

  9. mac的jvm调优工具

    安装好JDK之后调优工具所在位置为: /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/jvisualvm j ...

  10. jvm 调优 工具

    1.用于打开运行中的jvm进程的gc 监控日志以及查看相关参数设置:jinfo 2.其它工具如:jps.jstack.jstat.jmap

随机推荐

  1. python设计模式第六天【原型模式】

    1.定义 使用原型模式复制的对象与原来对象具有一样的结构和数据,有浅克隆和深克隆 2.应用场景 (1)希望复制原来对象的结构和数据胆步影响原来对象 3.代码实现 #!/usr/bin/env pyth ...

  2. Yii2后台管理系统常规单据模块最佳实践

    后台管理系统的常规单据通常包括数据,页面,功能:其中数据,页面,功能又可以细分如下: 分类  二级分类  主要内容  注意事项  例如 数据 数据库迁移脚本  用于数据表生成及转态回滚 1.是否需要增 ...

  3. onkeyup+onafterpaste 只能输入数字和小数点--转载

    JS判断只能是数字和小数点 1.文本框只能输入数字代码(小数点也不能输入)<input onkeyup="this.value=this.value.replace(/\D/g,'') ...

  4. css中绝对定位和相对定位详解

    相对定位relative和绝对定位absolute 相对定位 相对定位是标签在根据没加position样式前的位置来定位不会受父级标签的定位的影响,并且定位后不会脱离文本流,会占据原来的位置. 接下来 ...

  5. mybatis,mysql批量delete多个记录

    1.dao 接口中 Integer delete(List<UserDeviceRela> relas); 2.xml <delete id="delete" p ...

  6. THUWC2018游记

    前言 这次THUWC有pretest,非常不错.但还是要对拍. DAY1 上午先去报个到. 下午1:30开始比赛,状态还是很好的. 开场先看题. 发现t1是个联赛贪心题,就花了半个小时写完+拍完了. ...

  7. 【vijos1780】【NOIP2012】开车旅行 倍增

    题目描述 有\(n\)个城市,第\(i\)个城市的海拔为\(h_i\)且这\(n\)个城市的海拔互不相同.编号比较大的城市在东边.两个城市\(i,j\)之间的距离为\(|h_i-h_j|\) 小A和小 ...

  8. bzoj 2733 : [HNOI2012]永无乡 (线段树合并)

    Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以 ...

  9. 普通Splay详解

    预备知识: 二叉搜索树(BST) 至于BST,随便看一下就可以, 我们知道二叉搜索树是O(logN)的,那我们为什么要用平衡树呢? 之前我们了解到,BST的插入是小的往左子树走,大的往右子树走,如果凉 ...

  10. 【NOIP2018 Day1】题解

    T3 rp++; 今天题比较简单 而且考了很多嫌疑原题? 大家基本250+ 本蒟蒻...T3十分看脸 再次祝rp++; T1 积木大赛本赛嘛 如果d[i] < d[i - 1] ans += d ...