zoukankan      html  css  js  c++  java
  • 记录一次OOM分析过程

    工具:

    • jstat
    • jmap
    • jhat

    1.jstat查看gc情况

    S0C、S1C、S0U、S1U:Survivor 0/1区容量(Capacity)和使用量(Used)
    EC、EU:Eden区容量和使用量
    OC、OU:年老代容量和使用量
    PC、PU:永久代容量和使用量
    YGC、YGT:年轻代GC次数和GC耗时
    FGC、FGCT:Full GC次数和Full GC耗时
    GCT:GC总耗时
    

      

    这次遇到的情况是,old区到了指定的回收阀值触发fgc,但old区回收不了,持续增长(但一直频繁fgc)

    jvm配置如下:

    -server -XX:PermSize=64m -XX:MaxPermSize=128m -Xmn500m -Xms3000m -Xmx3000m -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=60 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/apps/oom/gc.hprof  -XX:ErrorFile=/var/log/java_error_%p.log

    2.当发现old区回收不了的时候,使用jmap分析内存情况。

    jmap -heap pid

    使用jmap -heap pid查看进程堆内存使用情况,包括使用的GC算法、堆配置参数和各代中堆内存使用情况。

    例如:

    Attaching to process ID 10253, please wait...
    Debugger attached successfully.
    Server compiler detected.
    JVM version is 24.65-b04
    
    using parallel threads in the new generation.
    using thread-local object allocation.
    Concurrent Mark-Sweep GC
    
    Heap Configuration:
       MinHeapFreeRatio = 40
       MaxHeapFreeRatio = 70
       MaxHeapSize      = 3145728000 (3000.0MB)
       NewSize          = 524288000 (500.0MB)
       MaxNewSize       = 524288000 (500.0MB)
       OldSize          = 5439488 (5.1875MB)
       NewRatio         = 2
       SurvivorRatio    = 8
       PermSize         = 67108864 (64.0MB)
       MaxPermSize      = 134217728 (128.0MB)
       G1HeapRegionSize = 0 (0.0MB)
    
    Heap Usage:
    New Generation (Eden + 1 Survivor Space):
       capacity = 471859200 (450.0MB)
       used     = 113244456 (107.99832916259766MB)
       free     = 358614744 (342.00167083740234MB)
       23.99962870279948% used
    Eden Space:
       capacity = 419430400 (400.0MB)
       used     = 66465208 (63.38616180419922MB)
       free     = 352965192 (336.6138381958008MB)
       15.846540451049805% used
    From Space:
       capacity = 52428800 (50.0MB)
       used     = 46779248 (44.61216735839844MB)
       free     = 5649552 (5.3878326416015625MB)
       89.22433471679688% used
    To Space:
       capacity = 52428800 (50.0MB)
       used     = 0 (0.0MB)
       free     = 52428800 (50.0MB)
       0.0% used
    concurrent mark-sweep generation:
       capacity = 2621440000 (2500.0MB)
       used     = 259229192 (247.22022247314453MB)
       free     = 2362210808 (2252.7797775268555MB)
       9.888808898925781% used
    Perm Generation:
       capacity = 67108864 (64.0MB)
       used     = 37059440 (35.34263610839844MB)
       free     = 30049424 (28.657363891601562MB)
       55.22286891937256% used
    
    19254 interned Strings occupying 2351584 bytes.
    

    jmap -heap 只能查看jvm各个区的详细使用情况,内存中到底有哪些数据(咬着old区不放)得用jmap -histo进行分析。

    jmap -histo[:live] pid

    例如:

    num     #instances         #bytes  class name
    ----------------------------------------------
       1:         32727       88492856  [I
       2:        369677       62058808  [C
       3:        145200       54408968  [B
       4:        545638       17460416  java.util.HashMap$Entry
       5:        451316       14442112  org.wltea.analyzer.dic.DictSegment
       6:        158024       10051408  [Ljava.lang.Object;
       7:         59193        8940656  <constMethodKlass>
       8:         59193        7588736  <methodKlass>
       9:          6105        7139824  <constantPoolKlass>
      10:         39329        6230272  [Ljava.util.HashMap$Entry;
      11:        255466        6131184  java.lang.String
      12:        182746        5847872  [Lorg.wltea.analyzer.dic.DictSegment;
      13:          6097        4220448  <instanceKlassKlass>
      14:          5064        3900032  <constantPoolCacheKlass>
      15:        100084        3202688  org.apache.lucene.document.LazyDocument$LazyField
      16:         78719        3148760  java.util.LinkedHashMap$Entry
      17:         11980        3120656  [S
      18:        122352        2936448  java.util.ArrayList
      19:          9747        2740192  [J
      20:         95649        2295576  java.util.LinkedList$Node
      21:         53484        2139360  org.apache.lucene.document.FieldType
      22:        125687        2010992  java.lang.Character
      23:         41021        1969008  org.apache.lucene.analysis.tokenattributes.PackedTokenAttributeImpl
      24:         53663        1913576  [Lorg.apache.lucene.util.automaton.Transition;
    

     class name是对象类型,说明如下:

    B  byte
    C  char
    D  double
    F  float
    I  int
    J  long
    Z  boolean
    [  数组,如[I表示int[]
    [L+类名 其他对象
    

    如果还需要看更加详细的信息,则使用:

    jmap -dump:format=b,file=dumpFileName pid

    dump出来的文件可以用MAT、VisualVM等工具查看,也可以使用jhat。

    jhat -port 9999 dumpFileName

    如果dump出来的文件过大,可能需要指定Xmx(jhat实际启动了一个web应用)。

    jhat -J-Xmx1000m -port 9999 dumpFileName

    启动成功后,则可以通过浏览器查看:

    ip:port

    例如:

    在该页面的最后面有一些查询工具,例如:OQL(object query language)

    例如上图查询的是长度大于256的int数组。

    ------------------------------------

    企业开发的时候,有可能碰到的问题:

    • oom
    • 内存泄露
    • 线程死锁
    • 锁争用
    • java进程消耗cpu过高 

    工具:

    • jps(java virtual machine process status tool)

    jps主要用来输出JVM中运行的进程状态信息。语法格式如下:

    jps [options] [hostid]

    q 不输出类名、Jar名和传入main方法的参数
    -m 输出传入main方法的参数
    -l 输出main类或Jar的全限名
    -v 输出传入JVM的参数
    
    • jstack

     jstack主要用来查看某个Java进程内的线程堆栈信息。

    检查过程:

    1)得到相应的进程号(ps -ef |grep ***)

    2)查询该进程对应的线程信息(top -Hp pid)

    这里的Pid需要转成16进制,后面需要用到。

    [apps@java1818 bin]$ printf "%x
    " 10831
    2a4f
    

    使用jstack进行分析

    [apps@java1818 bin]$ jstack 10253 | grep 2a4f
    "http-bio-2223-exec-172" daemon prio=10 tid=0x00007fb2d400a000 nid=0x2a4f waiting on condition [0x00007fb28c5c4000]
    

    也可以将信息dump到文件中进行分析,更加方便。  

      

    • jmap ( memory map ) / jhat ( java heap analysis tool )

     jmap用来查看堆内存使用状况,一般结合jhat使用。

    jmap -heap pid
    jmap -histo[:live] pid
    jmap -dump:format=b,file=dumpFileName pid
    

      

    • jstat

    堆内存 = 年轻代 + 年老代 + 永久代
    年轻代 = Eden区 + 两个Survivor区(From和To)
    

      

    • hprof ( heap/cpu profiling tool )

     hprof能够展现CPU使用率,统计堆内存使用情况。

    参考资料:

    http://my.oschina.net/feichexia/blog/196575

  • 相关阅读:
    android.permission
    Android 记住密码和自动登录界面的实现(SharedPreferences 的用法)
    人要怎样活在现实生活中
    viewpager---01
    Android ViewPager多页面滑动切换以及动画效果
    【205】C#实现远程桌面访问
    【204】显示3D大球球
    【203】利用UltraISO制作和刻录光盘映像的方法
    【202】ThinkPad手势&快捷键
    【201】SeaDAS代码
  • 原文地址:https://www.cnblogs.com/huangfox/p/4354991.html
Copyright © 2011-2022 走看看