一、分析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:\dump\heap.hprof <pid>

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

jcmd <pid> GC.heap_dump d:\dump\heap.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:\test.hprof
  指定 dump 文件存储路径。

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

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

三、jvisualvm使用

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

2、点击类选项卡

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

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

JAVA垃圾回收笔记的更多相关文章

  1. Java垃圾回收学习笔记

    通常来说,要写Java代码,你基本上都没必要听说垃圾回收这个概念的.这不,对于已经写了5年多Java代码的我来说,我还没有哪次经历说是需要使用垃圾回收方面的知识来解决问题的.但是,我依然督促自己花了几 ...

  2. Java 垃圾回收(GC) 泛读

    Java 垃圾回收(GC) 泛读 文章地址:https://segmentfault.com/a/1190000008922319 0. 序言 带着问题去看待 垃圾回收(GC) 会比较好,一般来说主要 ...

  3. 【转载】Java垃圾回收机制

    原文地址:http://www.importnew.com/19085.html Java垃圾回收机制 说到垃圾回收(Garbage Collection,GC),很多人就会自然而然地把它和Java联 ...

  4. 【转】深入理解 Java 垃圾回收机制

    深入理解 Java 垃圾回收机制   一.垃圾回收机制的意义 Java语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再 ...

  5. 深入理解java垃圾回收机制

    深入理解java垃圾回收机制---- 一.垃圾回收机制的意义 Java语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再 ...

  6. Java GC系列(2):Java垃圾回收是如何工作的?

    本文由 ImportNew - 伍翀 翻译自 javapapers. 目录 垃圾回收介绍 垃圾回收是如何工作的? 垃圾回收的类别 垃圾回收监视和分析 本教程是为了理解基本的Java垃圾回收以及它是如何 ...

  7. Java GC系列(1):Java垃圾回收简介

    本文由 ImportNew - 好好先生 翻译自 javapapers. Java的内存分配与回收全部由JVM垃圾回收进程自动完成.与C语言不同,Java开发者不需要自己编写代码实现垃圾回收.这是Ja ...

  8. Java垃圾回收介绍(译)

    在Java中,对象内存空间的分配与回收是由JVM中的垃圾回收进程自动完成的.与C语言不同的是,在Java中开发者不需要专门为垃圾回收写代码.这是使Java流行的众多特征之一,也帮助了程序员写出了更好的 ...

  9. [牛感悟系列]JAVA(1)理解JAVA垃圾回收

    理解JAVA垃圾回收的好处是什么?满足求知欲是一方面,编写更好的JAVA应用是另外一方面. 如果一个人对垃圾回收过程感兴趣,那表明他在应用程序开发领域有相当程度的经验.如果一个人在思考如何选择正确的垃 ...

随机推荐

  1. 用position: fixed;做个遮罩,怎么能让后面的View禁止滑动

    用一个view标签把代码包起来,当模态层出来时给它添加height:100%;position: absolute;overflow: hidden;.模态框消失时去掉样式      

  2. linux命名对文件的读写和退出

    vi xxx.txt 打开就能看到里面的内容.按 i 进入编辑模式,然后就可以输入内容了,也可以移动光标到你要删除内容的位置按删除键来删除内容.编辑完后可以按 Esc(键盘左上角) 进入命令模式.然后 ...

  3. php+mysqli实现批量执行插入、更新及删除数据的方法

    本文实例讲述了php+mysqli实现批量执行插入.更新及删除数据的方法.分享给大家供大家参考.具体如下: mysqli批量执行插入/更新/删除数据,函数为 multi_query(). 下面的代码只 ...

  4. ajax取消重复请求

    var pendingRequests = {}; $.ajaxPrefilter(function(options, originalOptions, jqXHR) { var key = opti ...

  5. C++ 类的继承六(多继承的二义性--虚基类)

    //多继承的二义性--虚基类(了解为主) #include<iostream> using namespace std; /* 多继承在现在的项目开发中一般不使用,他会增加项目的复杂度 * ...

  6. php 怎么查看是否开启了socket

    <?php if(extension_loaded('sockets')){ echo "已开启"; }else{ echo "未开启"; } ?>

  7. css横向 弹性盒子布局的一些属性

    <head> <meta charset="utf-8"> <meta name="viewport" content=" ...

  8. 12 个免费在线的 Web 网站性能测试工具

    https://www.oschina.net/news/21033/12-free-online-tools-for-website-testing

  9. 一入python深似海--变量和对象

    一.基本原理 Python中一切都是对象,变量是对象的引用. 这是一个普遍的法则.我们举个样例来说.Python是怎样来处理的. x = 'blue' y = 'green' z = x 当pytho ...

  10. IOS 预览pdf,word文档的集中方式

    在iPhone中可以很方便的预览文档文件,如:pdf.word等等,这篇文章将以PDF为例.介绍三种预览PDF的方式,又分别从本地pdf文档和网络上的pdf文档进行对比. 预览本地PDF文档: 1.使 ...