zoukankan      html  css  js  c++  java
  • JAVA垃圾回收笔记

    一、分析GC日志

    /**
     * @author : Hejinsheng
     * @date : 2019/1/18 0018
     * @Description: 模拟FULL GC/YOUNG GC
     * -Xms100M -Xmx100M -Xmn32m -XX:SurvivorRatio=8 -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError
     */
    public class GCTest {
    
        public static void main(String[] args) {
            List<Object> list = new ArrayList<>();
            for(int i=0;;i++){
                System.out.println(i);
                list.add(new byte[1024]);
            }
        }
    }
    

    打印的GC信息

    [Full GC (Ergonomics) [PSYoungGen: 26624K->26623K(29696K)] [ParOldGen: 69631K->69630K(69632K)] 96255K->96253K(99328K), [Metaspace: 3298K->3298K(1056768K)], 0.0200149 secs] [Times: user=0.03 sys=0.00, real=0.02 secs]
    [Full GC (Ergonomics) [PSYoungGen: 26624K->26623K(29696K)] [ParOldGen: 69631K->69631K(69632K)] 96255K->96255K(99328K), [Metaspace: 3298K->3298K(1056768K)], 0.0177546 secs] [Times: user=0.08 sys=0.00, real=0.02 secs]
    [Full GC (Allocation Failure) [PSYoungGen: 26623K->26623K(29696K)] [ParOldGen: 69631K->69613K(69632K)] 96255K->96236K(99328K), [Metaspace: 3298K->3298K(1056768K)], 0.0466197 secs] [Times: user=0.03 sys=0.00, real=0.05 secs]

    1. 最前面的数字217.539:代表GC发生的时间,从虚拟机启动开始算起

    2. GC日志开头的[GC和FULL GC]说明这次垃圾收集的停顿类型,而不是区分新生代和老年代的。

    FULL GC : 说明这次GC是发生了线程停顿Stop-The-World,如果是System.gc()方法所触发的收集,,那么在这里将显示[Full GC (System)

    3. [DefNew,[Tenured,[Perm表示GC发生的区域,这里显示的区域名称和使用的垃圾收集器是密切相关的

    1>在Serial收集器中新生代名为Default New Generation ,显示就是DefNew

    2>垃圾收集器ParNew中新生代名称就会变为[Parnew,意思为Parallel New Generation 

    3>如果采用Parrallel Scavenge收集器,那么它配套的新生代名称为PSYongGen

    老年代和永久代同理,名称由垃圾收集器决定

    4.[DefNew: 102646K->10770K(102976K), 0.0415902 secs] 239776K->153169K(331528K), 0.0416785 secs] [Times: user=0.03 sys=0.02, real=0.04 secs] 就这段而言,

    1>方括号内部102646K->10770K(102976K)的含义是GC前改内存区域已使用内存->GC后改内存区域使用容量(该内存区域总容量)

    2>方括号外 239776K->153169K(331528K)表示GC前java堆已使用容量->GC后java堆已使用容量(java堆总容量)

    3>在往后时间表示该内存区域gc清理用的时间

    4>[Times: user=0.03 sys=0.02, real=0.04 secs]

    这里面的user、sys和real与linux的time命令所输出的时间含义一致,分别表示用户态消耗的CPU时间、内核态消耗的CPU事件和操作从开始到结束经历的墙钟时间

    墙钟时间和CPU时间的区别是,墙钟时间包括各种非运算的等待耗时(i/o,线程阻塞),而CPU时间不包括这些,但是如果是多核,

    多线程会叠加这些CPU时间,此时user或sys时间超过real时间完全是正常的

    二、获取堆转储的几种方式

    Heap Dump 是 Java进程所使用的内存情况在某一时间的一次快照。以文件的形式持久化到磁盘中。
    Heap Dump的格式有很多种,而且不同的格式包含的信息也可能不一样。但总的来说,Heap Dump一般都包含了一个堆中的Java Objects, Class等基本信息。同时,当你在执行一个转储操作时,往往会触发一次GC,所以你转储得到的文件里包含的信息通常是有效的内容(包含比较少,或没有垃圾对象了) 。

    Heap Dump 包含的信息

    所有的对象信息
      对象的类信息、字段信息、原生值(int, long等)及引用值
    所有的类信息
      类加载器、类名、超类及静态字段
    垃圾回收的根对象
      根对象是指那些可以直接被虚拟机触及的对象
    线程栈及局部变量
      包含了转储时刻的线程调用栈信息和栈帧中的局部变量信息
    Heap Dump 获取方式

    1. 使用 jmap 命令生成 dump 文件

    jmap -dump:live,format=b,file=d:dumpheap.hprof <pid>

    2. 使用 jcmd 命令生成 dump 文件

    jcmd <pid> GC.heap_dump d:dumpheap.hprof

    3. 使用 JVM 参数获取 dump 文件

      1. -XX:+HeapDumpOnOutOfMemoryError
      当OutOfMemoryError发生时自动生成 Heap Dump 文件。

      这可是一个非常有用的参数,因为当你需要分析Java内存使用情况时,往往是在OOM(OutOfMemoryError)发生时。
      2. -XX:+HeapDumpBeforeFullGC
      当 JVM 执行 FullGC 前执行 dump。

      3. -XX:+HeapDumpAfterFullGC
      当 JVM 执行 FullGC 后执行 dump。

      4. -XX:+HeapDumpOnCtrlBreak
      交互式获取dump。在控制台按下快捷键Ctrl + Break时,JVM就会转存一下堆快照。

      5. -XX:HeapDumpPath=d: est.hprof
      指定 dump 文件存储路径。

      注意:JVM 生成 Heap Dump 的时候,虚拟机是暂停一切服务的。如果是线上系统执行 Heap Dump 时需要注意。

    分析 工具:jdk 自带的工具 jvisualvm、Eclipse memory analyzer(jmat)、JProfiler 等。

    三、jvisualvm使用

    1、点击文件-装入,载入dump下来的文件

    2、点击类选项卡

    3、根据上图分析实例数或占用大小比例较高的类,右键 “在实例视图中显示”,如

    找到可能发生内存泄漏或内存溢出的根对象

  • 相关阅读:
    SD卡测试
    测试人员可能会遇到的问题
    HDU 1024 Max Sum Plus Plus
    HDU 1176 免费馅饼
    HDU 1257 最少拦截系统
    HDU 1087 Super Jumping! Jumping! Jumping!
    poj 1328 Radar Installation
    poj 1753 Flip Game
    HDU 1003 Max Sum
    HDU 5592 ZYB's Premutation(BestCoder Round #65 C)
  • 原文地址:https://www.cnblogs.com/half-two-feet/p/10282315.html
Copyright © 2011-2022 走看看