JDK为我们提供的工具
jps
列出当前机器上正在运行的虚拟机进程
-q :仅仅显示VM 标示,不显示jar,class, main参数等信息.
-m:输出主函数传入的参数. 下的hello 就是在执行程序时从命令行输入的参数
-l: 输出应用程序主类完整package名称或jar完整名称.
-v: 列出jvm参数, -Xms20m -Xmx50m是启动程序指定的jvm参数
jstat
是用于监视虚拟机各种运行状态信息的命令行工具。它可以显示本地或者远程虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据,在没有GUI图形界面,只提供了纯文本控制台环境的服务器上,它将是运行期定位虚拟机性能问题的首选工具。
假设需要每250毫秒查询一次进程2764垃圾收集状况,一共查询20次,那命令应当是:jstat-gc 4600 250 20
jstat命令命令格式:
jstat [Options] vmid [interval] [count]
命令参数说明:
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容量
标志 | 说明 |
S0C | 年轻代中第一个survivor区的容量 (字节) |
S1C | 年轻代中第二个survivor区的容量 (字节) |
S0U | 年轻代中第一个survivor区目前已使用空间 (字节) |
S1U | 年轻代中第二个survivor区目前已使用空间 (字节) |
EC | 年轻代中Eden的容量 (字节) |
EU | 年轻代中Eden目前已使用空间 (字节) |
OC | Old代的容量 (字节) |
OU | Old代目前已使用空间 (字节) |
PC | Perm(持久代)的容量 (字节) |
PU | Perm(持久代)目前已使用空间 (字节) |
YGC | 从应用程序启动到采样时年轻代中gc次数 |
YGCT | 从应用程序启动到采样时年轻代中gc所用时间(s) |
FGC | 从应用程序启动到采样时old代(全gc)gc次数 |
FGCT | 从应用程序启动到采样时old代(全gc)gc所用时间(s) |
GCT | 从应用程序启动到采样时gc用的总时间(s) |
NGCMN | 年轻代(young)中初始化(最小)的大小 (字节) |
NGCMX | 年轻代(young)的最大容量 (字节) |
NGC | 年轻代(young)中当前的容量 (字节) |
OGCMN | old代中初始化(最小)的大小 (字节) |
OGCMX | old代的最大容量 (字节) |
OGC | old代当前新生成的容量 (字节) |
PGCMN | perm代中初始化(最小)的大小 (字节) |
PGCMX | perm代的最大容量 (字节) |
PGC | perm代当前新生成的容量 (字节) |
S0 | 年轻代中第一个survivor区已使用的占当前容量百分比 |
S1 | 年轻代中第二个survivor区已使用的占当前容量百分比 |
E | 年轻代中Eden已使用的占当前容量百分比 |
O | old代已使用的占当前容量百分比 |
P | perm代已使用的占当前容量百分比 |
S0CMX | 年轻代中第一个survivor区的最大容量 (字节) |
S1CMX | 年轻代中第二个survivor区的最大容量 (字节) |
ECMX | 年轻代中Eden的最大容量 (字节) |
DSS | 当前需要survivor区的容量 (字节)(Eden区已满) |
TT | 持有次数限制 |
MTT | 最大持有次数限制 |
jinfo
查看和修改虚拟机的参数
jinfo -sysprops 4600 可以查看由System.getProperties()取得的参数
jinfo
查看和修改虚拟机的参数
jinfo –sysprops 可以查看由System.getProperties()取得的参数
jinfo –flag 未被显式指定的参数的系统默认值
jinfo –flags(注意s)显示虚拟机的参数
jinfo –flag +[参数] 可以增加参数,但是仅限于由java -XX:+PrintFlagsFinal –version查询出来且
为manageable的参数
jinfo –flag -[参数] 可以去除参数
Thread.getAllStackTraces();
jmap
用于生成堆转储快照(一般称为heapdump或dump文件)。jmap的作用并不仅仅是为了获取dump文件,它还可以查询finalize执行队列、Java堆和永久代的详细信息,如空间使用率、当前用的是哪种收集器等。和jinfo命令一样,jmap有不少功能在Windows平台下都是受限的,除了生成dump文件的-dump选项和用于查看每个类的实例、空间占用统计的-histo选项在所有操作系统都提供之外,其余选项都只能在Linux/Solaris下使用。
jmap -dump:live,format=b,file=heap.bin <pid>
Sun JDK提供jhat(JVM Heap Analysis Tool)命令与jmap搭配使用,来分析jmap生成的堆转储快照。
jhat
jhat dump文件名 :
后屏幕显示“Server is ready.”的提示后,用户在浏览器中键入http://localhost:7000/就可以访问详情
jstack
(Stack Trace for Java)命令用于生成虚拟机当前时刻的线程快照。线程快照就是当前虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等都是导致线程长时间停顿的常见原因。
在代码中可以用java.lang.Thread类的getAllStackTraces()方法用于获取虚拟机中所有线程的StackTraceElement对象。使用这个方法可以通过简单的几行代码就完成jstack的大部分功能,在实际项目中不妨调用这个方法做个管理员页面,可以随时使用浏览器来查看线程堆栈。
管理远程进程需要在远程程序的启动参数中增加:
-Djava.rmi.server.hostname=…..
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=8888
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
visualvm
插件中心地址
https://visualvm.github.io
但是注意版本问题,不同的JDK所带的visualvm是不一样的,下载插件时需要下对应的版本。
浅堆和深堆
浅堆 :(Shallow Heap)是指一个对象所消耗的内存。例如,在32位系统中,一个对象引用会占据4个字节,一个int类型会占据4个字节,long型变量会占据8个字节,每个对象头需要占用8个字节。
深堆 :这个对象被GC回收后,可以真实释放的内存大小,也就是只能通过对象被直接或间接访问到的所有对象的集合。通俗地说,就是指仅被对象所持有的对象的集合。深堆是指对象的保留集中所有的对象的浅堆大小之和。
举例:对象A引用了C和D,对象B引用了C和E。那么对象A的浅堆大小只是A本身,不含C和D,而A的实际大小为A、C、D三者之和。而A的深堆大小为A与D之和,由于对象C还可以通过对象B访问到,因此不在对象A的深堆范围内。