在项目中遇到OOM(Out of Memory)的问题,为了分析内存和JVM的垃圾回收器GC问题,一并把JVM相关的一些工具也研究了一下:

  1. jps:Java进程查看工具,实际上它和Unix/Linux上面的ps命令的功能差不多
  2. jstat:Java内存使用情况监控工具
  3. jmap:输出JVM内存中对象的工具

这些工具位于JAVA_HOME/bin目录下

?

一,jps (Java Virtual Machine Process Status Tool) JVM进程状态工具

jps用来查看host上运行的所有java进程的pid(lvmid),一般情况下使用这个工具的目的只是为了找出运行的jvm进程ID,即lvmid,然后可以进一步使用其它的工具来监控和分析JVM,因此可以说这个工具并没有太多的功能。

如我本地只启动了visualVM,jps可以看到

? TEXT

 
1
2
2156 Jps
1932 Main

常用的几个参数:

-l 输出java应用程序的main class的完整包

-q 仅显示pid,不显示其它任何相关信息

-m 输出传递给main方法的参数

-v 输出传递给JVM的参数。在诊断JVM相关问题的时候,这个参数可以查看JVM相关参数的设置

如使用 jps -l -v 命令可以输出如下

? TEXT

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
C:\Oracle\Middleware\jdk160_05\bin>jps -l -v
5780 sun.tools.jps.Jps
-Dapplication.home=C:\Oracle\Middleware\jdk160_05 -Xms8m
 
1932 org/netbeans/Main -Xms24m -Xmx192m
-Dnetbeans.accept_license_class=com.sun.tools.visualvm.modules.startup.AcceptLicense
-Dsun.jvmstat.perdata.syncWaitMs=10000
-Djdk.home=C:/Oracle/Middleware/jdk160_05
-Dnetbeans.home=D:\Arone.Zhang\jvm\visualvm_111\platform9
-Dnetbeans.dirs=D:\Arone.Zhang\jvm\visualvm_111\visualvm;D:\Arone.Zhang\jvm\visualvm_111\profiler3
-Dnetbeans.user=C:\Users\Arone.Zhang\AppData\Roaming\.visualvm\1.1.1
-Dnetbeans.system_http_proxy=DIRECT
-Dnetbeans.system_http_non_proxy_hosts=
-Dsun.awt.keepWorkingSetOnMinimize=true

?

jps的官方描述:http://java.sun.com/j2se/1.5.0/docs/tooldocs/share/jps.html

?

二,jstat (Java Virtual Machine Statistics Monitoring Tool) JVM统计信息监控工具

jstat根据lvmid来实时监控Java应用程序的资源和性能,包括jvm的heap size和GC的回收状况,比起jps工具jstat要强大得多,同时使用起来也较复杂。

?

jstat有如下的生成结果选项(通过 jstat –options 来查看),jstat需要列出lvmid的统计信息,因此需要和jps配合使用

-class :显示加载类和卸载类的数量、所占空间大小和加载类和卸载类所花的时间

-compiler:显示VM实时编译的统计信息,包括编译任务执行的数量、编译任务失败的数量、变为无效的编译任务数量、执行编译任务所花费的时间等等

-gc:显示GC的堆信息,包括存活区、新生代区、永久区、发生GC的次数和所花费的时间

-gccapacity:显示JVM内存池中三代(young、old、perm)对象的使用和占用能力

-gccause:这个和-gcutil选项一样都是显示GC统计信息的汇总信息,只是包括了最后GC事件和当前GC事件

-gcnew:显示新生代对象的统计信息

-gcnewcapacity:显示新生代对象的信息和占用量

-gcold:显示老一代对象的统计信息

-gcoldcapacity:显示老一代对象的信息和占用量

-gcpermcapacity:显示永久代对象的信息和占用量

-gcutil:显示GC统计信息的汇总信息

-printcompilation:打印当前VM执行的信息

?

此工具中涉及到的永久代、老一代和新生代的概念和jdk的GC算法有密切的关系,关于GC的内容请查看Tuning Garbage Collection with the 5.0 JavaTM Virtual Machine

jstat使用的除了上面生成结果选项之外,还有收集统计信息的时间间隔和统计的次数,同时还可以控制输出结果的列标题如何出现。

? TEXT

 
1
2
3
4
5
6
7
8
C:\Oracle\Middleware\jdk160_05\bin>jstat -gcnew -t -h3 1932 30 5
Timestamp S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT
26638.9 192.0 192.0 0.0 192.0 1 15 96.0 1728.0 1472.7 12737 17.803
26639.0 192.0 192.0 0.0 192.0 1 15 96.0 1728.0 1472.7 12737 17.803
26639.0 192.0 192.0 0.0 192.0 1 15 96.0 1728.0 1472.7 12737 17.803
Timestamp S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT
26639.0 192.0 192.0 0.0 192.0 1 15 96.0 1728.0 1472.7 12737 17.803
26639.1 192.0 192.0 0.0 192.0 1 15 96.0 1728.0 1472.7 12737 17.803

?

上面的 -t 选项是用来打印timestamp,-hN选项是用来控制打印列标题,这个选项对于多屏输出结果的时候比较有用,因此上面的jstat -gcnew -t -h3 1932 30 5 代表针对lvmid为 1932 的Java进程收集新生代对象统计信息:包括打印时间戳、每隔3行打印一次标题、30ms统计一次、共统计5次

每个选项输出列的含义请查看官方文档,jstat的官方描述:http://java.sun.com/j2se/1.5.0/docs/tooldocs/share/jstat.html

虽然jstat提供了监控GC状态的强大功能,但是由于它是命令行,在实际问题的分析过程中难度比较高,因此市场上面出现了很多基于此命令的可视化工具,开源工具visualVM就是其中的佼佼者,JDK1.6之后,它已经包括在jdk中了。

?

关于如何使用visualVM来可视化监控JVM状况,后续将整理相关的文章。

?

三,jmap (Memory Map) JVM内存对象打印工具

jmap根据lvmid来Java进程的内存所有对象

?

首先根据选项打印出Java对象堆的直方图信息,包括Java类、类实例对象数量、在内存中占有量的大小以及类的完整包名,下面是缩减版本的直方图信息:

? TEXT

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
C:\Oracle\Middleware\jdk160_05\bin>jmap -histo 3432
 
num #instances #bytes class name
----------------------------------------------
1: 14644 20883096 [I
2: 69176 7689640
3: 111994 6561320 [C
4: 69176 5542192
5: 1933 4825592 [Ljavax.swing.text.GapContent$MarkData;
6: 100440 4480456
7: 6506 3771008
8: 90461 3618440 org.openide.util.RequestProcessor$Item
9: 90239 3609560 org.openide.util.RequestProcessor$EnqueueTask
......
3315: 1 8 sun.misc.Launcher$Factory
3316: 1 8 org.netbeans.core.windows.WindowSystemImpl
3317: 1 8 javax.swing.filechooser.WindowsFileSystemView
3318: 1 8 org.netbeans.ModuleFactory
Total 1767075 103137272

?

其次是将内存堆的信息dump成为一个二进制文件,供jhat这样的Java内存分析工具来使用,如下降Java内存对象堆dump为heap.bin文件:

? TEXT

 
1
2
3
C:\Oracle\Middleware\jdk160_05\bin>jmap -dump:format=b,file=heap.bin 3432
Dumping heap to C:\Oracle\Middleware\jdk160_05\bin\heap.bin ...
Heap dump file created

命令运行完成之后,在同目录下会生成一个heap.bin二进制内存对象堆文件

?

此工具使用比较简单,但是它对于分析内存溢出问题非常有用,目前有很多用来分析Java内存对象的工具,如收费的工具有:jprofiler,YourKit Java Profiler;而像Eclipse MAT则是优秀的内存对象分析开源工具,后续将整理相关的文章。

几个与JVM相关的JDK工具:jps, jstat, jmap的更多相关文章

  1. jvm系列(四):jvm调优-命令大全(jps jstat jmap jhat jstack jinfo)

    文章同步发布于github博客地址,阅读效果更佳,欢迎品尝 运用jvm自带的命令可以方便的在生产监控和打印堆栈的日志信息帮忙我们来定位问题!虽然jvm调优成熟的工具已经有很多:jconsole.大名鼎 ...

  2. [转]jvm调优-命令大全(jps jstat jmap jhat jstack jinfo)

    运用jvm自带的命令可以方便的在生产监控和打印堆栈的日志信息帮忙我们来定位问题!虽然jvm调优成熟的工具已经有很多:jconsole.大名鼎鼎的VisualVM,IBM的Memory Analyzer ...

  3. JVM调优 — 命令大全(jps jstat jmap jhat jstack jinfo)(转)

    运用jvm自带的命令可以方便的在生产监控和打印堆栈的日志信息帮忙我们来定位问题!虽然jvm调优成熟的工具已经有很多:jconsole.大名鼎鼎的VisualVM,IBM的Memory Analyzer ...

  4. jvm调优-命令大全(jps jstat jmap jhat jstack jinfo)

    现实企业级Java开发中,有时候我们会碰到下面这些问题: OutOfMemoryError,内存不足 内存泄露 线程死锁 锁争用(Lock Contention) Java进程消耗CPU过高 运用jv ...

  5. jvm性能监控(3)-jdk自带工具 jps jstack jmap

    一.概要: jps -l 查看现有的java进程 jps -l 显示所有正在运行的java进程id   jstack 查看Java线程      jstack -l pid; 做thread dump ...

  6. jvm 性能调优工具之 jstat 命令详解

    Jstat名称:Java Virtual Machine statistics monitoring tool 官方文档:https://docs.oracle.com/javase/1.5.0/do ...

  7. jvm 性能调优工具之 jstat

    概述 Jstat是JDK自带的一个轻量级小工具.全称“Java Virtual Machine statistics monitoring tool”,它位于java的bin目录下,主要利用JVM内建 ...

  8. 【Linux】在linux上java工具jps jstat jinfo等命令找不到怎么办

    一.yum安装方式 1)搜索openjdk-devel相关的安装包 yum search java|grep jdk 2)安装对应的版本 yum install -y java-1.8.0-openj ...

  9. 一、jdk工具之jps(JVM Process Status Tools)命令使用

    目录 一.jdk工具之jps(JVM Process Status Tools)命令使用 二.jdk命令之javah命令(C Header and Stub File Generator) 三.jdk ...

随机推荐

  1. Web安全之BurpSuite抓取HTTPS请求

    出现了问题,第一步要干什么呢? 当然是要去官方网站去找FAQ和help,先来练习一下英语 https://portswigger.net/burp/help/proxy_options_install ...

  2. 常用php操作redis命令整理(五)ZSET类型

    ZADD 向有序集合插入一个元素,元素关联一个数值,插入成功返回1,同时集合元素不可以重复, 如果元素已经存在返回 0 <?php var_dump($redis->zadd(,'A')) ...

  3. # 20145106 《Java程序设计》第3周学习总结

    教材学习内容总结 在本周的学习中,我看到了这样一句话:"使用java撰写程序几乎都是在使用对象(object),要产生对象必须先定义类(class),类是对象的设计图,对象是类的实例(ins ...

  4. ngular6开发不完全笔记(三)-- 报错指南

    router Uncaught Error: Template parse errors: 'router-outlet' is not a known element: If 'router-out ...

  5. POJ 3660 Cow ContestCow(Floyd传递闭包)题解

    题意:给出m个关系,问你能确定机头牛的排名 思路:要确定排名那必须要把他和其他n-1头牛比过才行,所以Floyd传递闭包,如果赢的+输的有n-1就能确定排名. 代码: #include<cstd ...

  6. Cannot perform runtime binding on a null reference

    一个方法的参数是dynamic  obj 方法内调用了obj.Header 但是外部传递进来的obj是null,然后就会报这个错.

  7. 【分页问题】elasticsearch 深分页问题以及解决方法

    本文主要参考: 1.https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-scroll.html ...

  8. [BZOJ1877][SDOI2009]SuperGCD

    题目大意 求两个个高精度数的gcd 题目解析 在学习gcd的时候,书上就记载了"更相减损术"这一方法 基于这种方法,我们进行优化,使得我们能快速求出两个大数的gcd 对于 \(a, ...

  9. Codeforces Beta Round #57 (Div. 2) A,B,C,D,E

    A. Ultra-Fast Mathematician time limit per test 2 seconds memory limit per test 256 megabytes input ...

  10. 使用 Redis

    Redis(https://redis.io/),既不像 SQLite 以表的形式存储数据,也不像 MongoDB 允许以嵌套结构存储和查询,它是一种内存数据库结构,即将数据缓存在内存中.它将键—值( ...