#
查看所有对象,包括活跃以及非活跃的
jmap
‐histo
<pid> | more
#
查看活跃对象
jmap
‐histo
:live <pid> | more
[root@node01 ~]
# jmap ‐histo:live 6219 | more
num
#instances #bytes class name
‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
1
:
37437 7914608
[C
2
:
34916 837984
java.lang.String
3
:
884 654848
[B
4
:
17188 550016
java.util.HashMap
$Node
5
:
3674 424968
java.lang.Class
6
:
6322 395512
[Ljava.lang.Object;
7
:
3738 328944
java.lang.reflect.Method
8
:
1028 208048
[Ljava.util.HashMap
$Node
;
9
:
2247 144264
[I
10
:
4305 137760
java.util.concurrent.ConcurrentHashMap
$Node
11
:
1270 109080
[Ljava.lang.String;
12
:
64 84128
[Ljava.util.concurrent.ConcurrentHashMap
$Node
;
13
:
1714 82272
java.util.HashMap
14
:
3285 70072
[Ljava.lang.Class;
15
:
2888 69312
java.util.ArrayList
16
:
3983 63728
java.lang.Object
17
:
1271 61008
org.apache.tomcat.util.digester.CallMethodRule
18
:
1518 60720
java.util.LinkedHashMap
$Entry
19
:
1671 53472
com.sun.org.apache.xerces.internal.xni.QName
20
:
88 50880
[Ljava.util.WeakHashMap
$Entry
;
21
:
618 49440
java.lang.reflect.Constructor
22
:
1545 49440
java.util.Hashtable
$Entry
23
:
1027 41080
java.util.TreeMap
$Entry
24
:
846 40608
org.apache.tomcat.util.modeler.AttributeInfo
25
:
142 38032
[S
26
:
946 37840
java.lang.ref.SoftReference
27
:
226 36816
[[C
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
#
对象说明
B byte
C char
D double
F float
I int
J long
Z boolean
[
数组,如
[I
表示
int[]
[L
+
类名 其他对象
4.3
、将内存使用情况
dump
到文件中
有些时候我们需要将
jvm
当前内存中的情况
dump
到文件中,然后对它进行分析,
jmap
也
是支持
dump
到文件中
#
用法:
jmap
‐dump
:format
=
b
,file
=
dumpFileName <pid>
可以看到已经在
/tmp
下生成了
dump.dat
的文件。
4.4
、通过
jhat
对
dump
文件进行分析
在上一小节中,我们将
jvm
的内存
dump
到文件中,这个文件是一个二进制的文件,不方
便查看,这时我们可以借助于
jhat
工具进行查看。
#
用法:
jhat
‐port
<port> <file>
#
示例:
[root@node01 tmp]
# jhat ‐port 9999 /tmp/dump.dat
Reading from /tmp/dump.dat...
Dump file created Mon Sep
10 01
:04:21 CST 2018
Snapshot read, resolving...
Resolving
204094
objects...
Chasing references, expect
40
dots........................................
Eliminating duplicate references........................................
Snapshot resolved.
Started HTTP server on port 9999
Server is ready
5
、实战:内存溢出的定位与分析
内存溢出在实际的生产环境中经常会遇到,比如,不断的将数据写入到一个集合中,出
现了死循环,读取超大的文件等等,都可能会造成内存溢出。
如果出现了内存溢出,首先我们需要定位到发生内存溢出的环节,并且进行分析,是正
常还是非正常情况,如果是正常的需求,就应该考虑加大内存的设置,如果是非正常需
求,那么就要对代码进行修改,修复这个
bug
。
首先,我们得先学会如何定位问题,然后再进行分析。如何定位问题呢,我们需要借助
于
jmap
与
MAT
工具进行定位分析。
接下来,我们模拟内存溢出的场景。
5.1
、模拟内存溢出
编写代码,向
List
集合中添加
100
万个字符串,每个字符串由
1000
个
UUID
组成。如果程
序能够正常执行,最后打印
ok
。
public class
TestJvmOutOfMemory
{
public static
void
main
(
String
[]
args
) {
List<
Object
> list =
new
ArrayList<>
();
for
(
int
i =
0
;
i <
10000000
;
i++
) {
String
str =
""
;
for
(
int
j =
0
;
j <
1000
;
j++
) {
str += UUID
.
randomUUID
().
toString
();
}
list
.
add
(
str
);
}
System
.
out
.
println
(
"ok"
);
}
}
6
、
jstack
的使用
有些时候我们需要查看下
jvm
中的线程执行情况,比如,发现服务器的
CPU
的负载突然增
高了、出现了死锁、死循环等,我们该如何分析呢?
由于程序是正常运行的,没有任何的输出,从日志方面也看不出什么问题,所以就需要
看下
jvm
的内部线程的执行情况,然后再进行分析查找出原因。
这个时候,就需要借助于
jstack
命令了,
jstack
的作用是将正在运行的
jvm
的线程情况进
行快照,并且打印出来:
#
用法:
jstack <pid>
[root@node01 bin]
# jstack 2203
Full thread dump Java HotSpot(TM)
64
‐Bit
Server VM (25.141‐b15 mixed
mode):