JVM 可视化工具 之 Java VisualVM
本文主要介绍JVM的可视化工具:jvisualvm。
基础知识
JVM参数
Linux系统,使用man java查看JVM参数
参数 | 含义 | 默认值 | 样例 |
---|---|---|---|
-Xms | 堆的初始Size | 物理内存的1/64 | -Xms128m |
-Xmx | 堆的最大Size,在生产环境,通常与-Xms设置成相同的值 | 物理内存的1/4 | -Xmx128m |
-Xmn | 年轻代的初始Size和最大Size(Eden+From Survior + To Survivor ) | -Xmn256m | |
-Xss | 线程的堆栈大小 | -Xss1m | |
-XX:NewSize=size | 年轻代的初始size | -XX:NewSize=256m | |
-XX:MaxNewSize=size | 年轻代的最大size | -XX:MaxNewSize=256m | |
-XX:NewRatio=ration | 年轻代(包括Eden和两个Survivor区)和老年代的比值 | 2 | -XX:NewRatio=4表示年轻代和年老代的占比是1:4,年轻代占整个堆的1/5。设置-Xms、-Xmx与-Xmn时,该参数不需要设置 |
-XX:SurvivorRatio | Eden区与Survivor区的比值 | 8 | |
-Xloggc:filename | Sets the file to which verbose GC events information should be redirected for logging. | -Xloggc:garbage-collection.log |
java -Xmx20m -Xms20m -XX:+HeapDumpOnOutOfMemoryError JavaHeapTest
1 public class JavaHeapTest{
2 public final static int MAX_SIZE = 2000000000;
3
4 private String oom;
5
6 private int length;
7
8 StringBuffer tempOOM = new StringBuffer();
9
10 public JavaHeapTest(int length){
11 this.length = length;
12
13 int i = 0;
14 while(i < length){
15 i++;
16
17 try{
18 tempOOM.append("a");
19
20 }catch(OutOfMemoryError e){
21 e.printStackTrace();
22 break;
23
24 }
25
26 }
27
28 this.oom = tempOOM.toString();
29
30 }
31
32
33 public String getOom(){
34 return oom;
35 }
36
37 public int getLength(){
38 return length;
39 }
40
41 public static void main(String args[]){
42 try{
43 if(args.length>0){
44 System.out.println("Main Thread Sleep....");
45 Thread.sleep(100000);
46 }else{
47 Thread.sleep(40000);
48 }
49 }catch(InterruptedException ignored){
50 ;
51 }
52 JavaHeapTest test = new JavaHeapTest(MAX_SIZE);
53
54 System.out.println(test.getOom().length());
55
56 }
57
58 }
~
JDK 常用命令
java
作用:运行java程序
语法:
#java [options] classname [args]
#java [options] -jar filename [args]
#java -XX:+PrintFlagsInitial /*打印JVM默认配置,其他参见 man java*/
参数 | 含义 |
---|---|
options | 命令行参数 |
classname | 程序主类 |
filename | Java Archive文件的文件名 |
args | 传递给main()方法的参数 |
jps
作用:查看本地系统或者远程系统上运行的JVM信息,包括pid、class name或者jar file name、JVM params、main params等
语法:
jps [-q] [-mlvV] [<hostid>]
参数 | 含义 |
---|---|
q | 仅显示pid |
m | 显示传给main()方法的参数 |
l | 显示class name或者 jar filename的全路径 |
v | 显示传递给JVM的参数 |
V | 显示pid以及class name或者jar filename |
例子:
#jps -v
30019 StringSample -Xms200m -Xmx200m -Xshare:off -XX:+PrintGCDetails
10660 Jps -Dapplication.home=/usr/lib/jvm/jdk1.8.0_144 -Xms8m
9959 Jstat -Dapplication.home=/usr/lib/jvm/jdk1.8.0_144 -Xms8m -Xms100m
jinfo
作用:查看JVM参数
jmap
作用:查看Java 程序的堆内存使用情况
语法:
#jmap [option] <pid>
#jmap [option] <core file>
#jmap [option] [server_id@]<remote server IP or hostname>
例子:
#jps
5665 Jps
30019 StringSample
#jmap -heap 30019
Attaching to process ID 30019, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.144-b01
using thread-local object allocation.
Parallel GC with 8 thread(s)
Heap Configuration:
MinHeapFreeRatio = 0
MaxHeapFreeRatio = 100
MaxHeapSize = 209715200 (200.0MB)
NewSize = 69730304 (66.5MB)
MaxNewSize = 69730304 (66.5MB)
OldSize = 139984896 (133.5MB)
NewRatio = 2
SurvivorRatio = 8
MetaspaceSize = 21807104 (20.796875MB)
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize = 17592186044415 MB
G1HeapRegionSize = 0 (0.0MB)
Heap Usage:
PS Young Generation
Eden Space:
capacity = 68681728 (65.5MB)
used = 67310072 (64.19188690185547MB)
free = 1371656 (1.3081130981445312MB)
98.00288076619155% used
From Space:
capacity = 524288 (0.5MB)
used = 65536 (0.0625MB)
free = 458752 (0.4375MB)
12.5% used
To Space:
capacity = 524288 (0.5MB)
used = 0 (0.0MB)
free = 524288 (0.5MB)
0.0% used
PS Old Generation
capacity = 139984896 (133.5MB)
used = 49064440 (46.79149627685547MB)
free = 90920456 (86.70850372314453MB)
35.049809945210086% used
6371 interned Strings occupying 566624 bytes.
#jmap -histo 30019
jstat
作用:监听JVM的统计信息
语法:
#jstat [ generalOption | outputOptions vmid [ interval[s|ms] [ count ] ]
例子:
#jps
#jstat -options
-class
-compiler
-gc
-gccapacity
-gccause
-gcmetacapacity
-gcnew
-gcnewcapacity
-gcold
-gcoldcapacity
-gcutil
-printcompilation
#jstat -class 30019
Loaded Bytes Unloaded Bytes Time
3625 7781.1 14 15.5 0.96
/**Loaded: 加载Java类数目 Bytes:加载Java类字节数**/
#jstat -gccause -t 30019 1s
Timestamp S0 S1 E O M CCS YGC YGCT FGC FGCT GCT LGCC GCC
23853.9 0.00 18.75 49.94 35.06 97.49 89.20 298333 1029.735 13 0.545 1030.280 Allocation Failure No GC
23854.9 0.00 12.50 28.00 35.06 97.49 89.20 298347 1029.757 13 0.545 1030.302 Allocation Failure No GC
23855.9 0.00 12.50 2.00 35.06 97.49 89.20 298361 1029.783 13 0.545 1030.329 Allocation Failure No GC
23856.9 0.00 12.50 0.00 35.06 97.49 89.20 298375 1029.811 13 0.545 1030.356 Allocation Failure No GC
Java VisualVM
VisualVM是一款免费的,集成了多个JDK工具(jconsole、jstat、jinfo、jstack、jmap)的轻量级性能分析的可视化工具,为程序开发人员,提供 Java程序的运行时信息(包括CPU、内存-堆或者MetaSpace、线程等),方便开发人员对应用程序进行故障诊断和性能优化。 —— [VisualVM官网]
如何安装
方法一: 自JavaSE JDK version 6, update 7以后,Java VisualVM作为JDK的一部分,位于$JDK_HOME/bin/jvisualvm,可以直接运行参考。
方法二:独立安装
1、安装VisualVM
下载VisualVM 14的zip压缩文件,解压到本地文件系统。具体下载地址 [VisualVM官网].
2、启动VisualVM
如下,导航到 bin目录,运行程序。
#cd bin
#visualvm.exe //windows 系统
//或者
#visualvm //linux系统
//
#man visualvm //查看用户
//--jdkhome <path> 指定JDK路径
内存分析
VisualVM通过监视JVM的Heap信息(包括Size、Used、Max)、加载类以及实例数目、结合线程,分析内存使用情况。例如:Heap是否持续增加?哪些线程占用内存多?哪些类的实例多?代码是否存在内存泄漏问题,不断创建对象,导致Eden Space急速消耗,引起Allocation Failed的Young Generation Collection,即YGC。
问题源码:不断增加的Eden Used Space
class StringSample{
private final static int MAX_INDEX_VALUE = 400000000;
public static void main(String args[]){
int index=0;
String msg = String.format("msg_%9s",index);
while(true){
msg = String.format("msg_%9s",++index);
}
}
}
使用visualVM之dump堆,分析堆
其他dump堆的方法:
#jmap -dump:fomrat=b,file=StringSample.hprof
参考
Java 8: 从永久代(PermGen)到元空间(Metaspace)
深入探究JVM(2) - 探秘Metaspace
* Java8 Metaspace
性能分析神器VisualVM
JVM系列三:JVM参数设置、分析