Java通过jvm自己管理内存,同时Java提供了一些命令行工具,用于查看内存使用情况。
这里主要介绍一下jstat、jmap命令以及相关工具。
命令参数说明:
Options,一般使用 -gcutil 或 -gc 查看gc 情况
pid,当前运行的 java进程号
interval,间隔时间,单位为秒或者毫秒
count,打印次数,如果缺省则打印无数次
Options 参数如下:
-gc:统计 jdk gc时 heap信息,以使用空间字节数表示
-gcutil:统计 gc时, heap情况,以使用空间的百分比表示
-class:统计 class loader行为信息
-compile:统计编译行为信息
-gccapacity:统计不同 generations(新生代,老年代,持久代)的 heap容量情况
-gccause:统计引起 gc的事件
-gcnew:统计 gc时,新生代的情况
-gcnewcapacity:统计 gc时,新生代 heap容量
-gcold:统计 gc时,老年代的情况
-gcoldcapacity:统计 gc时,老年代 heap容量
-gcpermcapacity:统计 gc时, permanent区 heap容量
示例
$ jstat -gc 12538 5000
每5 秒一次显示进程号为 12538的 java进成的 GC情况,结果如下图:
my.policy文件需要自己建立,是安全策略文件,因为 jdk对 jvm做了 jaas的安全检测,所以我们必须设置一些策略,使 jstatd被允许作网络操作,内容如下:
grant codebase " file:$JAVA_HOME/lib/tools.jar " {
permission java.security.AllPermission;
};
jmap命令格式:
jmap [ option ]
1)参数说明
pid:java进程 id
executable:产生 core dump的 java可执行程序
core:core dump文件
remote-hostname-or-IP:远程 debug服务的主机名或 ip
server-id:远程 debug服务的 id
2) option参数:
-heap
打印heap的概要信息,GC 使用的算法,heap的配置及使用情况 .
-histo[:live]
打印jvm heap 的直方图。输出类名、每个类的实例数目、对象占用大小。 VM的内部类名字开头会加上前缀 ”*”.
如果加上live 则只统计活的对象数量。
-dump:[live,]format=b,file=
使用hprof二进制形式,导出heap 内容到文件filename。
假如指定live 选项,那么只输出活的对象到文件 .
-finalizerinfo
打印正等候回收的对象的信息 .
-permstat
打印classload 和jvm heap 持久代的信息。
包含每个classloader 的名字、是否存活、地址、父 classloade、加载的 class数量、内部 String的数量和占用内存数。
-F
当pid没有响应的时候,与-dump或者 -histo共同使用,强制生成 dump文件或 histo信息 . 在这个模式下 ,live子参数无效 .
-J
传递参数给启动jmap 的jvm.
64位机上使用需要使用如下方式: jmap -J-d64 -heap pid
$ jmap -histo 2083 | jmap -histo:live 2083
可以观察heap中所有对象的情况(heap中所有生存的对象的情况)。包括对象数量和所占空间大小。
jmap输出的 class name结果中:
[C is a char[]
[S is a short[]
[I is a int[]
[B is a byte[]
[[I is a int[][]
heap输出实例
$ jmap -heap 12264
JVM version is 25.65-b01
using parallel threads in the new generation.
using thread-local object allocation.
Concurrent Mark-Sweep GC
Heap Configuration:
MinHeapFreeRatio = 40
MaxHeapFreeRatio = 70
MaxHeapSize = 8388608000 (8000.0MB)
NewSize = 2006515712 (1913.5625MB)
MaxNewSize = 2006515712 (1913.5625MB)
OldSize = 90636288 (86.4375MB)
NewRatio = 2
SurvivorRatio = 8
MetaspaceSize = 21807104 (20.796875MB)
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize = 17592186044415 MB
G1HeapRegionSize = 0 (0.0MB)
Heap Usage:
New Generation (Eden + 1 Survivor Space):
capacity = 1805910016 (1722.25MB)
used = 788045040 (751.5383148193359MB)
free = 1017864976 (970.7116851806641MB)
43.637004779755316% used
Eden Space:
capacity = 1605304320 (1530.9375MB)
used = 630378472 (601.1757583618164MB)
free = 974925848 (929.7617416381836MB)
39.26847166274367% used
From Space:
capacity = 200605696 (191.3125MB)
used = 157666568 (150.36255645751953MB)
free = 42939128 (40.94994354248047MB)
78.59525982751757% used
To Space:
capacity = 200605696 (191.3125MB)
used = 0 (0.0MB)
free = 200605696 (191.3125MB)
0.0% used
concurrent mark-sweep generation:
capacity = 6382092288 (6086.4375MB)
used = 4612472232 (4398.79630279541MB)
free = 1769620056 (1687.6411972045898MB)
72.27210174745753% used
18841 interned Strings occupying 1633048 bytes.
jmap 相关工具
jmap dump生成的 heap dump文件,可以使用 IBM HeapAnalyzer分析工具分析
下载:
https://www.ibm.com/developerworks/community/groups/service/html/communityview?communityUuid=4544bafe-c7a2-455f-9d43-eb866ea60091
运行:java –Xmx2g –jar ha456.jar
打开 heap dump文件
如图:
分析结果:mysql查询返回数据,以及某个实体对象nmfootballmatchs的list存储太多
1、适当修改程序,减少ArrayList数据存放
2、调整jvm参数满足当前需求
jinfo可以从 core文件里面知道崩溃的 Java应用程序的配置信息。
命令额格式:$ jinfo pid