线上问题排查思路

若用户反馈线上服务请求无响应,可以按照以下步骤进行排查。

一、确认服务器内存使用情况

执行free命令,看看服务器内存是否正常。

 total        used        free      shared  buff/cache   available
 Mem:       16256764     7583240     2177924     2901216     6495600     5437168
 Swap:       2097148        1280     2095868

看起来服务器内存是正常的。

二、确认服务器磁盘使用情况

执行df -h命令,查看磁盘使用情况。

文件系统                  容量    已用  可用  已用%  挂载点
xxxxxxxx                 7.8G     0   7.8G    5%   /xx
……

磁盘空间看起来也是充足的。

三、查看哪个进程占用内存多

输入top命令,然后按 shift p,最前面的就是占用内存最多的。

 PID     USER     PR  NI    VIRT     RES    SHR S     %CPU %MEM   TIME+      COMMAND
32297   xxxxxx    20   0    109.7g   4.7g   4.0g S   46.2 30.2    160554:47    java

这里可以获取到占用内存最多的pid。

四、查看线程的堆栈信息

执行jstack <pid>,会显示线程的状态。

Full thread dump OpenJDK 64-Bit Server VM (17+35-2724 mixed mode, sharing):

Threads class SMR info:
_java_thread_list=0x00007f24080015b0, length=41, elements={
0x00007f266c0899e0, 0x00007f266c08b050, 0x00007f266c091d60, 0x00007f266c093280,
0x00007f266c0948a0, 0x00007f266c0964a0, 0x00007f266c097c00, 0x00007f266c0a12a0,
0x00007f266c0befe0, 0x00007f266c0fa7d0, 0x00007f266c23c6b0, 0x00007f266c26dab0,
0x00007f266c425430, 0x00007f266c5ce320, 0x00007f266c6a3ca0, 0x00007f266c6e9790,
0x00007f266c9297f0, 0x00007f266c92d740, 0x00007f266c95d4a0, 0x00007f266c027640,
0x00007f23b8005600, 0x00007f23dc55f2c0, 0x00007f23dc5705c0, 0x00007f23bc0b8bc0,
0x00007f23bc15ebf0, 0x00007f23bc1e0cd0, 0x00007f23b800b850, 0x00007f23b800c2e0,
0x00007f23b800d370, 0x00007f23b800e9d0, 0x00007f23b800fbd0, 0x00007f23b8010ee0,
0x00007f23b8012220, 0x00007f23c4439b80, 0x00007f23c4006500, 0x00007f23c46ae980,
0x00007f23544eeb00, 0x00007f237c406d00, 0x00007f23a829ba30, 0x00007f23c46b2560,
0x00007f2408000a90
}

"Reference Handler" #2 daemon prio=10 os_prio=0 cpu=1463269.24ms elapsed=23238405.12s tid=0x00007f266c0899e0 nid=0x7e38 waiting on condition  [0x00007f26542be000]
   java.lang.Thread.State: RUNNABLE
        at java.lang.ref.Reference.waitForReferencePendingList(java.base@17/Native Method)
        at java.lang.ref.Reference.processPendingReferences(java.base@17/Reference.java:253)
        at java.lang.ref.Reference$ReferenceHandler.run(java.base@17/Reference.java:215)

如果有死锁,就会有下面这种:

java.lang.Thread.State: BLOCKED
     at xxxxxx1
     - waiting to lock <0xxxxxx>
     - locked <1xxxxx>
java.lang.Thread.State: BLOCKED
     at xxxxxx2
     - waiting to lock <1xxxxxx>
     - locked <0xxxxx>
五、查看堆内存占用情况

执行jmap -heap <pid>命令,可以看到堆内存的使用情况。

Attaching to process ID 5064, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.271-b09

using thread-local object allocation.
Parallel GC with 8 thread(s)

Heap Configuration:
   MinHeapFreeRatio         = 0
   MaxHeapFreeRatio         = 100
   MaxHeapSize              = 536870912 (512.0MB)
   NewSize                  = 268435456 (256.0MB)
   MaxNewSize               = 268435456 (256.0MB)
   OldSize                  = 268435456 (256.0MB)
   NewRatio                 = 2
   SurvivorRatio            = 8
   MetaspaceSize            = 134217728 (128.0MB)
   CompressedClassSpaceSize = 260046848 (248.0MB)
   MaxMetaspaceSize         = 268435456 (256.0MB)
   G1HeapRegionSize         = 0 (0.0MB)

Heap Usage:
PS Young Generation
Eden Space:
   capacity = 241172480 (230.0MB)
   used     = 94437072 (90.06221008300781MB)
   free     = 146735408 (139.9377899169922MB)
   39.15748264478601% used
From Space:
   capacity = 13107200 (12.5MB)
   used     = 3045992 (2.9048843383789062MB)
   free     = 10061208 (9.595115661621094MB)
   23.23907470703125% used
To Space:
   capacity = 12582912 (12.0MB)
   used     = 0 (0.0MB)
   free     = 12582912 (12.0MB)
   0.0% used
PS Old Generation
   capacity = 268435456 (256.0MB)
   used     = 84914376 (80.98065948486328MB)
   free     = 183521080 (175.01934051513672MB)
   31.63307011127472% used

46153 interned Strings occupying 5019920 bytes.

这里可以看到伊甸园区、from区、to区和老年代的内存占用情况,如果老年代99.99%了,那就是堆内存溢出了。

六、查看堆内存中内存占用前10的对象信息

jmap -histo:live <pid> | head -n 10
执行这个命令,可以看到内存占用前10的对象信息。

num     #instances         #bytes  class name
----------------------------------------------
   1:        165329       18150792  [C
   2:        163258        3918192  java.lang.String
   3:         40481        3562328  java.lang.reflect.Method
   4:         28014        2844936  [Ljava.lang.Object;
   5:         67703        2166496  java.util.concurrent.ConcurrentHashMap$Node
   6:          7919        2106384  [B
   7:         17131        1934896  java.lang.Class

如果这里看到有自己写的类对象,那可能就可以找到问题了。

七、分析内存溢出问题

确定了是哪一个节点有问题,那么先把节点的流量切走。
如果第六步没分析出来是什么导致内存溢出,可以按如下步骤排查。

1. 导出dump文件
jmap -dump:format=b,live,file=<fileName>.hprof <pid>
执行该命令,可以导出名为fileName.hprof的dump文件

2. 分析dump文件
这里介绍使用mat工具分析dump文件。

  • 先点击mat工具的 window ---> preferences ---> memory Analyzer,把 keep unreachable objects 勾选上,勾上了会保留不可达对象;
  • 点击 file ---> open heap dump,选择刚才的dump文件,等待几分钟,mat工具会生成一个默认的报告;
  • 默认报告里会列出problems,点击details就可以看到问题详情,一般会列出有问题的对象;
  • 选择有问题的对象,右键Merge Shortest Paths to GC Roots ---> exclude weak references
  • 然后再Java Basics ---> Thread Details,这样就可以看到线程详情,线程详情中就会有错误信息,可以定位到在代码的哪一行报错了;

如果默认报告按照上面的方式定位不到具体代码,那可以尝试以下步骤:

  • 在overview页点击histogram,然后按照retained heap排序;
  • 然后选择默认排在前面的对象,右键merge shortest path to GC Roots
  • 然后选择线程,Java Basics ---> Thread Details,一个个地看详情详情,一般看前几个就可以定位到问题了。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,393评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,790评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,391评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,703评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,613评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,003评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,507评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,158评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,300评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,256评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,274评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,984评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,569评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,662评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,899评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,268评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,840评论 2 339

推荐阅读更多精彩内容