JVM-GC调优,一文详解JDK监控和故障处理命令及常见故障分析

JVM 的定位系统问题时,知识和经验是关键基础,数据是依据、工具是运用知识处理数据的手段

数据包括:运行日志、异常堆栈、GC日志、线程快照(thread dump、javacore文件)、堆转储快照(headdump / hprof 文件)

一、调优命令

JDK监控和故障处理命令,在bin目录下有:jps、 jstat、jmap、jhat、jstack、jinfo

  • jps:显示虚拟机进程,常用如:jps -l -v
  • jstat:收集虚拟机各方面的运行数据,常用如:jps-gcutil 2764jstat -gc 2764 250 20
  • jinfo:显示虚拟机配置信息
  • jmap:生成虚拟机内存转储快照(headdump 文件),常用如:jmap -dump:live,format=b,file=dump.hprof 28920
  • jhat:用于分析headdump 文件,他会建立一个http/html 的服务器,让客户可以在浏览器上查看分析结果,常用如:jhat dump.hprof
  • jstack: 显示虚拟机线程快照,常用如:jstack -l 11494

下面做一 一介绍

二、Jps

显示指定系统内所有的HotSpot虚拟机进程,

格式 :

jps - [hostid]

options 参数:

  -q:只输出LVMID,省略主类的名称
  -m:输出新建启动时传递给主类main()函数的参数
  -l:输出主类的全名,如果进程执行的是Jar包,输出Jar路径
  -v:输出虚拟机进程启动时JVM参数

其中[option]、[hostid]参数也可以不写

一般使用:

jps -l -m

三、Jstat

用于监视虚拟机运行时状态信息的命令,它可以显示出虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据。

格式

jstat - [-t] [-h] [ []]
  • vmid: 进程号,interval 和count :表示查询间隔和次数
  • options 参数如下
-class:监视类装载、卸载熟练、总空间以及类装载所消耗的时间
-gc : 监视堆状况,包括Eden区、两个survivor区、老年代、永久代等容量、已用空间和GC 时间合计等信息
-gccapacity:监视内容和 -gc基本相同,但输出主要关注堆各个区域使用到最大,最小空间
-gcutil:监视内容和 -gc基本相同,但输出主要关注已使用空间占总空间的百分比
-gccause:与 -gcutil一样,额外输出导致上次GC产生的原因
-gcnew:监视新生代GC状况
-gcnewcapacity:监视内容和 -gcnew 基本相同,输出输出主要关注使用到的最大、最小空间
-gcold:监视老年代GC状况
-gcoldcapacity:监视内容和 -gcold 基本相同,输出输出主要关注使用到的最大、最小空间
-gcpermcapacity:输出永久代使用的最大、最小空间
-compiler:输出JIT 编译期编译过的方法、耗时等信息
-printcompilation:输出已经被JIT编译的方法

一般使用:

jps-gcutil 2764 //输出的是已使用空间占总空间的百分比

jstat -gc 2764 250 20 //每隔250ms输出2764的gc情况,一共输出20次

四、Jinfo

作用是实时查看和调整虚拟机运行参数。 之前的jps -v口令只能查看到显示指定的参数,如果想要查看未被显示指定的参数的值就要使用jinfo口令

格式

jinfo [option vmid]

vmid: 进程号

option参数

-flag : 输出指定args参数的值
-flags : 不需要args参数,输出所有JVM参数的值
-sysprops : 输出系统属性,等同于System.getProperties()

一般使用:jinfo -flag 11494

五、Jmap

用于生成heap dump文件,如果不使用这个命令,还阔以使用-XX:+HeapDumpOnOutOfMemoryError参数来让虚拟机出现OOM的时候·自动生成dump文件(阿里开发手册推荐)。说明:OOM 的发生是有概率的,甚至相隔数月才出现一例,出错时的堆内信息对解决问题非常有帮助。

jmap不仅能生成dump文件,还阔以查询finalize执行队列、Java堆和永久代的详细信息,如当前使用率、当前使用的是哪种收集器等。

格式

jmap - [vmid]

option 参数

-dump : 生成堆转储快照
-finalizerinfo : 显示在F-Queue队列等待Finalizer线程执行finalizer方法的对象
-heap : 显示Java堆详细信息
-histo : 显示堆中对象的统计信息
-permstat : to print permanent generation statistics
-F : 当-dump没有响应时,强制生成dump快照

一般使用 :

jmap -dump:live,format=b,file=dump.hprof 28920

dump堆到文件,format指定输出格式,live指明是活着的对象,file指定文件名

dump.hprof这个后缀是为了后续可以直接用MAT(Memory Anlysis Tool)打开。

六、Jhat

用来分析jmap生成的dump;与jmap搭配使用;jhat内置了一个微型的HTTP/HTML服务器,生成dump的分析结果后,可以在浏览器中查看。

在此要注意,一般不会直接在服务器上进行分析,因为jhat是一个耗时并且耗费硬件资源的过程,一般把服务器生成的dump文件复制到本地或其他机器上进行分析。

格式

jhat [dumpfile]

七、Jstack

用于生成java虚拟机当前时刻的线程快照。线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等。 如果java程序崩溃生成core文件,jstack工具可以用来获得core文件的java stack和native stack的信息,从而可以轻松地知道java程序是如何崩溃和在程序何处发生问题。另外,jstack工具还可以附属到正在运行的java程序中,看到当时运行的java程序的java stack和native stack的信息, 如果现在运行的java程序呈现hung的状态,jstack是非常有用的。

格式

jstack [option] LVMID

option参数

-F : 当正常输出请求不被响应时,强制输出线程堆栈
-l : 除堆栈外,显示关于锁的附加信息
-m : 如果调用到本地方法的话,可以显示C/C++的堆栈

一般使用:

jstack -l 11494

八、调优工具

1. jconsole

  • jdk /bin 目录下,单机jconsole.exe 启动启动
  • 自动搜索本机运行的所有虚拟机进程,不需要用户自己在使用jps 来查询

GChisto是一款专业分析gc日志的工具,可以通过gc日志来分析:Minor GC、full gc的时间、频率等等,通过列表、报表、图表等不同的形式来反应gc的情况。

GC Easy:推荐此工具进行gc分析;这是一个web工具,在线使用非常方便,进入官网,讲打包好的zip或者gz为后缀的压缩包上传,过一会就会拿到分析结果。

2. VisualVM

jdk 集成的分析工具,在jdk /bin 目录下,单机jvisualvm.exe 启动

3. Oracle Java Mission Control

jdk 集成的分析工具,在jdk /bin 目录下,单机jmc.exe 启动

九、常见问题分析

1. 查找CPU飙升的原因

问题分析步骤:

  • 首先,需要知道哪个进程占用CPU比较高,
  • 其次,需要知道占用CPU高的那个进程中的哪些线程占用CPU比较高,
  • 然后,需要知道这些线程的stack trace。

问题解决步骤:

①. top和pgrep来查看系统中Java进程的CPU占用情况。

  • 命令如下:top -p pgrep -d , java
  • pgrep:进程号,top -p:进程的信息。记录下CPU占用率最高的那个进程号。

②. top来查看进程中CPU占用最高的那些线程

  • top -Hp 12345
  • 假定12345为占用CPU高的进程号。-H是显示该进程中线程的CPU占用情况。同样,记录下CPU占用率高的那些线程号。

③. ctrl+H 切换到线程模式,找到占用cpu最高的线程。并把线程号转化为十六进制printf "%x\n" <线程ID>

④. 通过jstack导出Java应用中线程的stack trace(堆栈轨迹)

  • jstack 12345

注意:因为top中显示的线程号是10进制,jstack的输出结果中的线程号是16进制,所以只需要把top中看到线程号转换成16进制

小结一下,我们通过top和jstack来找到CPU占用高的线程的stack trace,可以使用Eclipse Memory Analyzer插件分析

2. Java堆溢出和泄漏

①. 内存溢出

程序在申请内存时,没有足够的内存空间供其使用

危害:容易受攻击
影响因素如下几大类:

  • 内存中加载的数据量过于庞大,如一次从数据库取出过多数据
  • 集合类中有对对象的引用,使用完后未清空,使得JVM不能回收
  • 代码中存在死循环或循环产生过多重复的对象实体

解决方案:

  • 修改JVM启动参数,直接增加内存
  • 检查错误日志,是否有其他异常或错误;
  • 对代码进行走查和分析,找出可能发生内存溢出的位置
  • 重点排查:数据库的取值,死循环和递归调用

②. 内存泄漏

无法释放已申请的内存空间

危害:频繁GC、运行崩溃
影响因素如下几大类:

  • 静态集合类引起内存泄露
  • 当集合里面的对象属性被修改后,再调用remove()方法时不起作用。
Set<Person> set = new HashSet<Person>();
Person p3 = new Person("唐僧","pwd1",25);
p3.setAge(2); //修改p3的年龄,此时p3元素对应的hashcode值发生改变
set.remove(p3); //此时remove不掉,造成内存泄漏
  • 监听器。释放对象时没有删除监听器。
  • 各种连接 ,比如数据库连接
  • 单例对象持有外部对象的引用

解决办法:使用工具jconsole分析

堆的最小值-Xms参数,最大值-Xmx参数

//代码实现堆溢出:---> 无限循环创建 对象
List list =new ArrayList();
int i=0;
while(true){
    list.add(new byte[5*1024*1024]);//----------->就是这一步
    System.out.println("分配次数:"+(++i))
}

③. Java栈溢出

栈溢出SOF定义:线程请求的栈深度超过虚拟机允许的最大深度

  • 无论是由于栈帧太大还是栈容量太小,当内存无法分配时都是OOM异常。
  • 虚拟机栈溢出:深度溢出:递归方法;广度溢出:大数组,建立多线程
//代码实现栈泄漏---> 方法无限递归调用
public void add(int i){
    add(i+1);
}

# 链接 Java程序员福利"常用资料分享"

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,001评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,210评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,874评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,001评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,022评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,005评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,929评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,742评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,193评论 1 309
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,427评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,583评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,305评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,911评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,564评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,731评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,581评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,478评论 2 352

推荐阅读更多精彩内容