zoukankan      html  css  js  c++  java
  • JVM调优工具

    JMap

    首先要知道Java进程的pid。

    Windows:

    ..

    ..

    ..

    Linux:

    ps -ef | grep java

    查看堆栈信息(jmap -heap pid)

    jmap -heap 8512
    Attaching to process ID 8512, please wait...
    Debugger attached successfully.
    Server compiler detected.
    JVM version is 25.161-b12
    
    using thread-local object allocation.
    Parallel GC with 8 thread(s)
    
    Heap Configuration:
       MinHeapFreeRatio         = 0
       MaxHeapFreeRatio         = 100
       MaxHeapSize              = 2128609280 (2030.0MB)
       NewSize                  = 44564480 (42.5MB)
       MaxNewSize               = 709361664 (676.5MB)
       OldSize                  = 89653248 (85.5MB)
       NewRatio                 = 2
       SurvivorRatio            = 8
       MetaspaceSize            = 21807104 (20.796875MB)
       CompressedClassSpaceSize = 1073741824 (1024.0MB)
       MaxMetaspaceSize         = 17592186044415 MB
       G1HeapRegionSize         = 0 (0.0MB)
    
    Heap Usage:
    PS Young Generation
    Eden Space:
       capacity = 68157440 (65.0MB)
       used     = 57053032 (54.410011291503906MB)
       free     = 11104408 (10.589988708496094MB)
       83.70770967923679% used
    From Space:
       capacity = 5242880 (5.0MB)
       used     = 3113008 (2.9687957763671875MB)
       free     = 2129872 (2.0312042236328125MB)
       59.37591552734375% used
    To Space:
       capacity = 3670016 (3.5MB)
       used     = 0 (0.0MB)
       free     = 3670016 (3.5MB)
       0.0% used
    PS Old Generation
       capacity = 89653248 (85.5MB)
       used     = 49152 (0.046875MB)
       free     = 89604096 (85.453125MB)
       0.05482456140350877% used
    
    3998 interned Strings occupying 342784 bytes.

    打印等待回收的对象信息(jmap -finalizerinfo pid)

    jmap -finalizerinfo 8512
    Attaching to process ID 8512, please wait...
    Debugger attached successfully.
    Server compiler detected.
    JVM version is 25.161-b12
    Number of objects pending for finalization: 0

     打印堆里面对象的统计信息:对象数量、占用大小、类名(jmap -histo:live pid | more)

    jmap -histo:live 8512 | more
    
     num     #instances         #bytes  class name
    ----------------------------------------------
       1:          9728        1016408  [C
       2:          1650         303784  [B
       3:          9441         226584  java.lang.String
       4:          1821         205672  java.lang.Class
       5:          1285          92520  org.apache.zookeeper.data.StatPersisted
       6:          1735          87008  [Ljava.lang.Object;
       7:          2385          76320  java.util.HashMap$Node
       8:          2322          74304  java.util.concurrent.ConcurrentHashMap$Node
       9:          1199          57552  java.util.HashMap
      10:           783          54312  [I
      11:           658          45208  [Ljava.util.HashMap$Node;
      12:          1285          41120  org.apache.zookeeper.server.DataNode
      13:           437          38456  java.lang.reflect.Method
      14:           502          36144  org.apache.zookeeper.server.Request
      15:           882          35280  java.util.TreeMap$Entry
      16:           501          24048  org.apache.zookeeper.txn.TxnHeader
      17:           889          21336  java.util.LinkedList$Node
      18:           582          21296  [Ljava.lang.String;
      19:          1049          16784  java.util.HashSet
      20:           501          16032  org.apache.zookeeper.server.quorum.QuorumPacket
      21:           399          15960  java.lang.ref.SoftReference
      22:            31          15952  [Ljava.util.concurrent.ConcurrentHashMap$Node;

    打印类加载器统计信息(jmap -clstats pid)

    jmap -clstats  8512
    Attaching to process ID 8512, please wait...
    Debugger attached successfully.
    Server compiler detected.
    JVM version is 25.161-b12
    finding class loader instances ..done.
    computing per loader stat ..done.
    please wait.. computing liveness....................................liveness analysis may be inaccurate ...
    class_loader    classes    bytes    parent_loader    alive?    type
    
    <bootstrap>    1359    2420845      null      live    <internal>
    0x000000008128cef8    1    1474      null      dead    sun/reflect/DelegatingClassLoader@0x0000000017289df8
    0x000000008128d088    1    880      null      dead    sun/reflect/DelegatingClassLoader@0x0000000017289df8
    0x000000008128d218    1    880      null      dead    sun/reflect/DelegatingClassLoader@0x0000000017289df8
    0x00000000814621d0    0    0    0x000000008120b6c8    dead    java/util/ResourceBundle$RBClassLoader@0x0000000017303798
    0x000000008120b6c8    358    716069    0x000000008120b728    live    sun/misc/Launcher$AppClassLoader@0x000000001728f6a0
    0x000000008120b728    3    2574      null      live    sun/misc/Launcher$ExtClassLoader@0x000000001728fa48
    0x000000008128cfc0    1    880      null      dead    sun/reflect/DelegatingClassLoader@0x0000000017289df8
    0x000000008128d150    1    880      null      dead    sun/reflect/DelegatingClassLoader@0x0000000017289df8
    
    total = 9    1725    3144482        N/A        alive=3, dead=6        N/A    

     把堆信息生成一个文件(jmap -dump:live,format=b,file=heap.bin <pid>)

    [d:]$ jmap -dump:live,format=b,file=heap.bin 8512
    Dumping heap to D:heap.bin ...
    Heap dump file created

     之后,我们利用Mat来分析,下载 Eclipse Memory Analyzer

     

    ..

    下载完解压

    ...

    ..

    ..

    ..打开我们刚才生成的文件

     

    ..

     ..看效果

    ..

    JStat

    每隔一段时间输出GC情况(jstat -gcutil pid inteval)

    [d:]$ jstat -gcutil 8512 3000
      S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT   
      0.00   0.00   0.94   7.26  96.88  93.14      7    0.061     2    0.022    0.082
      0.00   0.00   0.94   7.26  96.88  93.14      7    0.061     2    0.022    0.082
      0.00   0.00   0.94   7.26  96.88  93.14      7    0.061     2    0.022    0.082
      0.00   0.00   0.94   7.26  96.88  93.14      7    0.061     2    0.022    0.082
      0.00   0.00   0.94   7.26  96.88  93.14      7    0.061     2    0.022    0.082
      0.00   0.00   0.94   7.26  96.88  93.14      7    0.061     2    0.022    0.082
      0.00   0.00   0.94   7.26  96.88  93.14      7    0.061     2    0.022    0.082
      0.00   0.00   0.94   7.26  96.88  93.14      7    0.061     2    0.022    0.082
      0.00   0.00   0.94   7.26  96.88  93.14      7    0.061     2    0.022    0.082
      0.00   0.00   0.94   7.26  96.88  93.14      7    0.061     2    0.022    0.082
      0.00   0.00   0.94   7.26  96.88  93.14      7    0.061     2    0.022    0.082
      0.00   0.00   0.94   7.26  96.88  93.14      7    0.061     2    0.022    0.082
      0.00   0.00   0.94   7.26  96.88  93.14      7    0.061     2    0.022    0.082
      0.00   0.00   0.94   7.26  96.88  93.14      7    0.061     2    0.022    0.082
      0.00   0.00   0.94   7.26  96.88  93.14      7    0.061     2    0.022    0.082
      0.00   0.00   0.94   7.26  96.88  93.14      7    0.061     2    0.022    0.082

    参数:

    S0        from区已使用容量的百分比 
    S1        to区已使用容量的百分比 
    E         伊甸区已使用容量的百分比 
    O         老年代已使用容量的百分比 
    M         元数据空间利用率
    CCS       压缩类空间利用率
    YGC       从应用程序启动到采样时年轻代中gc次数
    YGCT      从应用程序启动到采样时年轻代中gc所用时间(s)
    FGC       从应用程序启动到采样时old代(全gc)gc次数
    FGCT      从应用程序启动到采样时old代(全gc)gc所用时间(s)
    GCT       从应用程序启动到采样时gc用的总时间(s)

    还有另外一个方法,输出的要全面一些

    [d:]$ jstat -gc 8512 3000
     S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT   
    4096.0 3584.0  0.0    0.0   133120.0  1257.0   37376.0     2715.3   9600.0 9300.8 1152.0 1073.0      7    0.061   2      0.022    0.082
    4096.0 3584.0  0.0    0.0   133120.0  1257.0   37376.0     2715.3   9600.0 9300.8 1152.0 1073.0      7    0.061   2      0.022    0.082
    4096.0 3584.0  0.0    0.0   133120.0  1257.0   37376.0     2715.3   9600.0 9300.8 1152.0 1073.0      7    0.061   2      0.022    0.082
    4096.0 3584.0  0.0    0.0   133120.0  1257.0   37376.0     2715.3   9600.0 9300.8 1152.0 1073.0      7    0.061   2      0.022    0.082

     参数:

    S0C:   当前from区容量
    S1C:   当前to区容量
    S0U:   from区已使用的容量
    S1U:   to区已使用的容量
    EC:    当前伊甸区的容量
    EU:    伊甸区已使用的容量
    OC:    老年代的容量
    OU:    老年代已使用的容量
    MC:    元空间容量
    MU:    元空间已使用容量
    CCSC:   压缩类空间容量
    CCSU:   已使用的压缩类空间
    YGC:   年轻代gc次数
    YGCT:   年轻代gc时间
    FGC:   full gc 次数
    FGCT:  Full gc时间
    GCT:   总gc时间

    场景:Full GC时间很长,并且GC之前堆内存是稳步上升的

    要么是内存泄漏,要么是垃圾回收出了问题。

    第一步你要看一下堆里对象是否异常

    jmap -histo:live 【pid】 | more

    然后看一下GC情况是否出现了异常的回收时间

    jstat -gc 【pid】【interval】

    再看一下内存分配是否出现了问题

    jmap -heap 【pid】

    关于GC,对于CMS和G1是有区别的。

    G1收集器处理Eden区是根据智能算法分配内存的。比如第一次回收发现年轻代只有200M,不够用,便设置成800M;第二次回收虽然年轻代有800M,但是仍然不够用,便再次增加比如1800M...之后发现1800M足够满足要求了,便将年轻代大小控制在这个值。

    CMS则不负责年轻代大小的自适应,如果你设置小了,在极端情况就会出现漫长的Full GC。

    设置新生代大小:-xmn1500m

    GC日志

    你可以在启动参数里加上 -XX:+PrintGCDetails 这样在发生GC就会打印日志

    然后利用 ps -ef | grep java 查看

    测试一下的话,在IDEA里的Edit Configurations设置

    先确定一下你目前的配置(我的年轻代只有42.5MB)

    jmap -heap 36068
    
    Attaching to process ID
    36068, please wait... Debugger attached successfully. Server compiler detected. JVM version is 25.161-b12 using thread-local object allocation. Parallel GC with 8 thread(s) Heap Configuration: MinHeapFreeRatio = 0 MaxHeapFreeRatio = 100 MaxHeapSize = 2128609280 (2030.0MB) NewSize = 44564480 (42.5MB) MaxNewSize = 709361664 (676.5MB) OldSize = 89653248 (85.5MB) NewRatio = 2 SurvivorRatio = 8 MetaspaceSize = 21807104 (20.796875MB) CompressedClassSpaceSize = 1073741824 (1024.0MB) MaxMetaspaceSize = 17592186044415 MB G1HeapRegionSize = 0 (0.0MB) Heap Usage: PS Young Generation Eden Space: capacity = 545259520 (520.0MB) used = 463909488 (442.41856384277344MB) free = 81350032 (77.58143615722656MB) 85.0804930466872% used From Space: capacity = 4718592 (4.5MB) used = 1015808 (0.96875MB) free = 3702784 (3.53125MB) 21.52777777777778% used To Space: capacity = 4718592 (4.5MB) used = 0 (0.0MB) free = 4718592 (4.5MB) 0.0% used PS Old Generation capacity = 89653248 (85.5MB) used = 3002576 (2.8634796142578125MB) free = 86650672 (82.63652038574219MB) 3.349098964044225% used 4700 interned Strings occupying 404664 bytes.

    查看用的什么收集器(目前不是G1收集器)

    java -XX:+PrintCommandLineFlags -version
    -XX:InitialHeapSize=132970112 -XX:MaxHeapSize=2127521792 -XX:+PrintCommandLineFl ags -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesInd ividualAllocation -XX:+UseParallelGC java version "1.8.0_161" Java(TM) SE Runtime Environment (build 1.8.0_161-b12) Java HotSpot(TM) 64-Bit Server VM (build 25.161-b12, mixed mode)

    测试

    public static void main(String[] args) throws Exception {
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < 10000000; i++){
            list.add(i);
        }
    
        Thread.sleep(10000);
        System.out.println("==================Exit==================");
    }

    输出:(发生了好多次GC)

    [GC (Allocation Failure) [PSYoungGen: 33280K->5100K(38400K)] 33280K->20309K(125952K), 0.0287241 secs] [Times: user=0.08 sys=0.00, real=0.03 secs] 
    [GC (Allocation Failure) [PSYoungGen: 38380K->5109K(71680K)] 53589K->41777K(159232K), 0.0325626 secs] [Times: user=0.13 sys=0.00, real=0.03 secs] 
    [GC (Allocation Failure) [PSYoungGen: 56608K->5093K(71680K)] 93276K->92393K(159232K), 0.0835488 secs] [Times: user=0.36 sys=0.00, real=0.08 secs] 
    [Full GC (Ergonomics) [PSYoungGen: 5093K->0K(71680K)] [ParOldGen: 87300K->81512K(194560K)] 92393K->81512K(266240K), [Metaspace: 3484K->3484K(1056768K)], 1.2747203 secs] [Times: user=4.23 sys=0.03, real=1.28 secs] 
    [GC (Allocation Failure) [PSYoungGen: 66560K->5120K(103936K)] 184127K->158535K(298496K), 0.2367500 secs] [Times: user=0.97 sys=0.00, real=0.24 secs] 
    [Full GC (Ergonomics) [PSYoungGen: 5120K->0K(103936K)] [ParOldGen: 153415K->142402K(306176K)] 158535K->142402K(410112K), [Metaspace: 3987K->3987K(1056768K)], 1.2205739 secs] [Times: user=5.96 sys=0.00, real=1.22 secs] 
    [GC (Allocation Failure) [PSYoungGen: 98816K->5120K(138240K)] 241218K->239348K(444416K), 0.1228611 secs] [Times: user=0.48 sys=0.02, real=0.12 secs] 
    [Full GC (Ergonomics) [PSYoungGen: 5120K->0K(138240K)] [ParOldGen: 234228K->202870K(459776K)] 239348K->202870K(598016K), [Metaspace: 3988K->3988K(1056768K)], 1.8345978 secs] [Times: user=9.27 sys=0.00, real=1.84 secs] 
    ==================Exit==================
    Heap
     PSYoungGen      total 138240K, used 11827K [0x00000000d5b80000, 0x00000000e9b00000, 0x0000000100000000)
      eden space 133120K, 8% used [0x00000000d5b80000,0x00000000d670cf70,0x00000000ddd80000)
      from space 5120K, 0% used [0x00000000ddd80000,0x00000000ddd80000,0x00000000de280000)
      to   space 95232K, 0% used [0x00000000e3e00000,0x00000000e3e00000,0x00000000e9b00000)
     ParOldGen       total 459776K, used 202870K [0x0000000081200000, 0x000000009d300000, 0x00000000d5b80000)
      object space 459776K, 44% used [0x0000000081200000,0x000000008d81d8a0,0x000000009d300000)
     Metaspace       used 3995K, capacity 4568K, committed 4864K, reserved 1056768K
      class space    used 435K, capacity 460K, committed 512K, reserved 1048576K

    换成G1试试

    再次运行一遍上面代码

    [GC pause (G1 Evacuation Pause) (young), 0.0435845 secs]
       [Eden: 20.0M(20.0M)->0.0B(3072.0K) Survivors: 0.0B->3072.0K Heap: 32.7M(128.0M)->28.8M(128.0M)]
    ...
    [GC pause (G1 Evacuation Pause) (young), 0.0299648 secs]
       [Eden: 3072.0K(3072.0K)->0.0B(11.0M) Survivors: 3072.0K->1024.0K Heap: 31.8M(128.0M)->34.7M(256.0M)]
    ... 
    [GC pause (G1 Evacuation Pause) (young), 0.0356263 secs]
       [Eden: 11.0M(11.0M)->0.0B(23.0M) Survivors: 1024.0K->2048.0K Heap: 63.1M(256.0M)->64.6M(512.0M)]
    ...
    [GC pause (G1 Evacuation Pause) (young), 0.0447098 secs]
       [Eden: 23.0M(23.0M)->0.0B(36.0M) Survivors: 2048.0K->4096.0K Heap: 103.2M(512.0M)->105.2M(816.0M)]
    ...
    [GC pause (G1 Evacuation Pause) (young), 0.0506044 secs]
       [Eden: 36.0M(36.0M)->0.0B(47.0M) Survivors: 4096.0K->5120.0K Heap: 164.7M(816.0M)->167.7M(1059.0M)]
    ...
    [GC pause (G1 Evacuation Pause) (young), 0.0679058 secs]
       [Eden: 47.0M(47.0M)->0.0B(55.0M) Survivors: 5120.0K->7168.0K Heap: 249.9M(1059.0M)->251.4M(1254.0M)]
    
    ==================Exit==================
    Heap
     garbage-first heap   total 1284096K, used 330981K [0x0000000081200000, 0x0000000081302730, 0x0000000100000000)
      region size 1024K, 27 young (27648K), 7 survivors (7168K)
     Metaspace       used 3995K, capacity 4568K, committed 4864K, reserved 1056768K
      class space    used 435K, capacity 460K, committed 512K, reserved 1048576K

    其中省略了无关代码,可以发现G1收集器可以优化Eden区的大小。

    -XX:+PrintGCDetails 输出GC的详细日志
    -XX:+PrintGCDateStamps 输出GC的时间
    -XX:+PrintHeapAtGC GC的前后打印出堆的信息
    -Xloggc:../logs/gc.log 日志文件的输出路径

     参考:https://docs.oracle.com/javase/8/docs/technotes/tools/windows/jstat.html

  • 相关阅读:
    可变参数函数总结
    小例子一步一步解释“函数调用过程中栈的变化过程”
    自己动手实现C标准库中sqrt()函数
    无符号整数翻转函数实现reverse_bits(unsigned int value)
    stdarg.h源代码
    判断两个字符串s1 s2所含字符是否相同
    亚马逊20120915网上机试第一题:atoi函数
    [wp7软件]wp7~~HTC官方软件~~集合贴~~
    [wp7软件]wp7~~相册加密软件~~集合贴~~
    [wp7软件]wp7~~密码管理软件~~集合贴~~
  • 原文地址:https://www.cnblogs.com/LUA123/p/9995974.html
Copyright © 2011-2022 走看看