JDK 工具 解决 JAVA 服务疑难杂症

1. 介绍

在JAVA的世界里,我们通常喜欢用熟悉的工具在本地环境去解决线上生产服务中遇到的问题。不幸的是,由于各种原因并不是所有问题都能复现. 比如你可能并不会真正的访问到你的线上服务产生的数据。

本文将介绍一些JDK 的工具和第三方的工具类帮助你解决线上环境的应用故障问题

2. 故障解决场景

2.1. 获取正在运行的 jvm 列表

获取一系列的正在运行中的 JVM,他们的进程ID,运行命令参数。有时你会发现同一个应用会有两个或者多个实例在做同样的事情

无参执行 jcmd 命令,将会输出正在运行的 JVM 列表:

> jcmd

25377 sun.tools.jcmd.JCmd
25293
25358 org.jetbrains.idea.maven.server.RemoteMavenServer

可以通过 jcmd help 命令看到对应的 JVM 可用的命令

>jcmd 25358 help

25358:
The following commands are available:
VM.native_memory
ManagementAgent.stop
ManagementAgent.start_local
ManagementAgent.start
GC.rotate_log
Thread.print
GC.class_stats
GC.class_histogram
GC.heap_dump
GC.run_finalization
GC.run
VM.uptime
VM.flags
VM.system_properties
VM.command_line
VM.version
help

For more information about a specific command use 'help <command>'.

输入 jcmd <PID> 具体命令 

> jcmd 25358 GC.heap_dump

25358:
java.lang.IllegalArgumentException: The argument 'filename' is mandatory.

 jcmd <PID> help GC.heap_dump 获得该命令的详细参数信息

>jcmd 25358 help GC.heap_dump

25358:
GC.heap_dump
Generate a HPROF format dump of the Java heap.

Impact: High: Depends on Java heap size and content. Request a full GC unless the '-all' option is specified.

Permission: java.lang.management.ManagementPermission(monitor)

Syntax : GC.heap_dump [options] <filename>

Arguments:
    filename :  Name of the dump file (STRING, no default value)

Options: (options must be specified using the <key> or <key>=<value> syntax)
    -all : [optional] Dump all objects, including unreachable objects (BOOLEAN, false)

2.2. 生成内存快照

jcmd 为生成 HPROF 内存快照提供了一个便利的接口. 仅仅执行 jcmd GC.heap_dump 命令 . 注意这个文件需要你指定绝对路径才会放到你想放的地方,最好文件以 .hprof 为后缀名结尾。

在一个内存快照生成完之后,可以用 VisualVM(JDK内置工具) 打开,并且可以用它来分析堆栈内存等问题。

1.还有一些其他的稳定的工具可以处理分析 hprof 文件, NetBeans, Eclipse Memory Analyzer, YourKit 等,多多尝试,找到一个最适合自己的

2. 也可以使用 jmap -dump:live,file=  来生成内存堆栈快照.但是它的问题是没有官方文档的支持。

2.3. 分析类分布图

如果你想知道哪里发生了内存泄漏,可能只需要在内存堆里面找到某种类型的一些类。

用jcmd <PID> 输出类的分布:

jcmd 25358 GC.class_histogram

jmap -histo:live

下面是 jcmd  GC.class_histogram 命令的部分输出内容

25358:

 num     #instances         #bytes  class name
----------------------------------------------
   1:         10682        1368104  [C
   2:           923         814744  [B
   3:          1584         619512  [I
   4:          3206         354456  java.lang.Class
   5:         10605         254520  java.lang.String
   6:          4352         174080  org.apache.lucene.index.FreqProxTermsWriter$PostingList
   7:          2441         152400  [Ljava.lang.Object;
   8:          4382         140224  java.util.concurrent.ConcurrentHashMap$Node
   9:          2783         111320  java.util.LinkedHashMap$Entry
  10:          1028          98264  [Ljava.util.HashMap$Node;
  11:          2905          92960  java.util.HashMap$Node
  12:          3825          61200  java.lang.Object
  13:           136          58208  [Lorg.apache.lucene.index.RawPostingList;
  14:           549          48312  java.lang.reflect.Method
  15:            40          41376  [Ljava.util.concurrent.ConcurrentHashMap$Node;
  16:           543          39096  java.lang.reflect.Field
  17:           600          33600  java.util.LinkedHashMap
  18:           616          29568  java.util.HashMap
  19:          1079          25896  com.google.inject.TypeLiteral

.....

1092:             1             16  sun.rmi.transport.proxy.RMIDirectSocketFactory
1093:             1             16  sun.rmi.transport.tcp.TCPChannel$1
1094:             1             16  sun.rmi.transport.tcp.TCPTransport$1
1095:             1             16  sun.util.calendar.Gregorian
1096:             1             16  sun.util.locale.provider.AuxLocaleProviderAdapter$NullProvider
1097:             1             16  sun.util.locale.provider.CalendarDataUtility$CalendarWeekParameterGetter
1098:             1             16  sun.util.locale.provider.SPILocaleProviderAdapter
1099:             1             16  sun.util.resources.LocaleData
1100:             1             16  sun.util.resources.LocaleData$LocaleDataResourceBundleControl
Total         76067        5282688

注意上面显示的数字仅仅是该对象 – 不包含任何子对象. 

可以用 grep 命令查找你想看的对象的数量,如果该对象的数量超出了正常范围,就可以生成一个 内存快照,用内存分析工具来分析它。

2.4. 生成线程快照

有时 java 应用会出现假死的状况,诱发假死的原因有很多种:死锁,磁盘IO过高 或者一个非常低效的算法。当假死情况发生时,需要知道应用的线程执行情况,每个线程都维持了哪些锁。

可以在任何系统上执行 jstack 查看 当前线程的运行快照

jstack -l

Found one Java-level deadlock:
=============================
"Thread-1":
  waiting to lock monitor 0x00007fa2f7813348 (object 0x000000079596c068, a java.lang.Object),
  which is held by "Thread-0"
"Thread-0":
  waiting to lock monitor 0x00007fa2f88ceca8 (object 0x000000079596c078, a java.lang.Object),
  which is held by "Thread-1"

Java stack information for the threads listed above:
===================================================
"Thread-1":
    at com.sidepro.utils.DeadLockclass.run(JStackDemo.java:47)
    - waiting to lock <0x000000079596c068> (a java.lang.Object)
    - locked <0x000000079596c078> (a java.lang.Object)
    at java.lang.Thread.run(Thread.java:745)
"Thread-0":
    at com.sidepro.utils.DeadLockclass.run(JStackDemo.java:34)
    - waiting to lock <0x000000079596c078> (a java.lang.Object)
    - locked <0x000000079596c068> (a java.lang.Object)
    at java.lang.Thread.run(Thread.java:745)

Found 1 deadlock.

上面所有提及的工具只适合快速排查. 对于更深层次的分析,推荐 Java Filght Recorder

翻译来源:http://java-performance.info/java-server-application-troubleshooting-using-jdk-tools/

微信扫码关注:

转载于:https://my.oschina.net/igeeker/blog/817065

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值