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:\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垃圾回收笔记的更多相关文章
- Java垃圾回收学习笔记
通常来说,要写Java代码,你基本上都没必要听说垃圾回收这个概念的.这不,对于已经写了5年多Java代码的我来说,我还没有哪次经历说是需要使用垃圾回收方面的知识来解决问题的.但是,我依然督促自己花了几 ...
- Java 垃圾回收(GC) 泛读
Java 垃圾回收(GC) 泛读 文章地址:https://segmentfault.com/a/1190000008922319 0. 序言 带着问题去看待 垃圾回收(GC) 会比较好,一般来说主要 ...
- 【转载】Java垃圾回收机制
原文地址:http://www.importnew.com/19085.html Java垃圾回收机制 说到垃圾回收(Garbage Collection,GC),很多人就会自然而然地把它和Java联 ...
- 【转】深入理解 Java 垃圾回收机制
深入理解 Java 垃圾回收机制 一.垃圾回收机制的意义 Java语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再 ...
- 深入理解java垃圾回收机制
深入理解java垃圾回收机制---- 一.垃圾回收机制的意义 Java语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再 ...
- Java GC系列(2):Java垃圾回收是如何工作的?
本文由 ImportNew - 伍翀 翻译自 javapapers. 目录 垃圾回收介绍 垃圾回收是如何工作的? 垃圾回收的类别 垃圾回收监视和分析 本教程是为了理解基本的Java垃圾回收以及它是如何 ...
- Java GC系列(1):Java垃圾回收简介
本文由 ImportNew - 好好先生 翻译自 javapapers. Java的内存分配与回收全部由JVM垃圾回收进程自动完成.与C语言不同,Java开发者不需要自己编写代码实现垃圾回收.这是Ja ...
- Java垃圾回收介绍(译)
在Java中,对象内存空间的分配与回收是由JVM中的垃圾回收进程自动完成的.与C语言不同的是,在Java中开发者不需要专门为垃圾回收写代码.这是使Java流行的众多特征之一,也帮助了程序员写出了更好的 ...
- [牛感悟系列]JAVA(1)理解JAVA垃圾回收
理解JAVA垃圾回收的好处是什么?满足求知欲是一方面,编写更好的JAVA应用是另外一方面. 如果一个人对垃圾回收过程感兴趣,那表明他在应用程序开发领域有相当程度的经验.如果一个人在思考如何选择正确的垃 ...
随机推荐
- jmeter插件JMeterPlugins-Standard 压力测试
Jmeter有插件提供用来给用户监控所测试的服务器的资源使用 情况,需要有Jmeter客户端插件和服务端插件 1.客户端插件 需要在https://jmeter-plugins.org/downloa ...
- HTML5课程
1.新语义化标签:section.header.footer.nav.article.aside.figure.dialog.time.meter.mark.progress.video 2.最新的属 ...
- C# 各版本的新特性
http://www.cnblogs.com/JeffreySun/archive/2012/11/14/2770211.html
- Node.js模块 require和 exports
https://liuzhichao.com/p/1669.html http://www.cnblogs.com/pigtail/archive/2013/01/14/2859555.html
- el表达式的首字母大小写问题
EL表达式获取对象属性的原理是这样的: 以表达式${user.name}为例 EL表达式会根据name去User类里寻找这个name的get方法,此时会自动把name首字母大写并加上get前缀,一旦找 ...
- BZOJ 3362 Navigation Nightmare 带权并查集
题目大意:给定一些点之间的位置关系,求两个点之间的曼哈顿距离 此题土豪题.只是POJ也有一道相同的题,能够刷一下 别被题目坑到了,这题不强制在线.把询问离线处理就可以 然后就是带权并查集的问题了.. ...
- mysql 暴力破解 root账号密码
测试数据库的root账号密码大家都忘记了,好吧,那我们就暴力破解吧 1.找到my.cnf vi /etc/my.cnf在[mysqld]的段中加上一句:skip-grant-tables例如:[mys ...
- LoadLibrary失敗,GetLastError 返回127錯誤
該原因一般是由於DLL或其依賴的DLL使用了高版本的API,而在低系統中運行時,找不到該函數所引發的錯誤. 比如:該函數:InterlockedExchange64, 看MSDN: Client Re ...
- GitHub上整理的一些工具【转】
技术站点 Hacker News:非常棒的针对编程的链接聚合网站 Programming reddit:同上 MSDN:微软相关的官方技术集中地,主要是文档类 infoq:企业级应用,关注软件开发领域 ...
- 用vector构造自动扩容的二维数组
#include <iostream> #include <string> #include <vector> using namespace std; int m ...