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、根据上图分析实例数或占用大小比例较高的类,右键 “在实例视图中显示”,如

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

  • 相关阅读:
    实现发送邮件
    c#操作sqlite(包含中文支持)
    C# & SQLite
    卸载impala
    kudu集成impala
    Kudu的卸载(cdh)
    Kudu的集群安装(1.6.0-cdh5.14.0)
    ELK日志平台搭建
    logstash之OutPut插件
    logstash之Filter插件
  • 原文地址:https://www.cnblogs.com/half-two-feet/p/10282315.html
Copyright © 2011-2022 走看看