垃圾回收日志与算法深度解读
经过前面对于JVM垃圾回收学习了纯理论相关的东东,这次则要开始用代码编写大量的实验来对理论进行佐证,下面开始,先在IntelliJ IDEA工程中新建一个全新的包:
![](/assets/blank.gif)
然后新建一个类:
![](/assets/blank.gif)
接下来则会编写一个超级简单的程序,程序虽简单,但是通过增加一些JVM的参数可以用简单的程序来阐述JVM垃圾回收的很多知识点,所以意义还是挺大的,具体如下:
![](/assets/blank.gif)
哇,确实是简单,但是这里有个注意点:就是对于这个byte类型的数组其实里面存放的是为0的原生类型,可以打印看一下:
![](/assets/blank.gif)
而如果是引用类型的数组则里面每个存放的是null,需要明白,接下来多创建几个byte数组:
![](/assets/blank.gif)
目前来看这是一个非常非常之low的程序,但是如果咱们给JVM增加一些运行参数,再输出看到的东东则会大不一样,下面来增加一些启动参数:
![](/assets/blank.gif)
![](/assets/blank.gif)
这里有意将堆空间设置得较小以便可以供咱们观察GC的情况,继续:
![](/assets/blank.gif)
![](/assets/blank.gif)
还有最后一个参数:
![](/assets/blank.gif)
这代表啥意思呢?其实它代表新生代的比例,如之前理论所介绍:
![](/assets/blank.gif)
也就是这里的配置就代表新生代的区域是8:1:1,也就是Eden空间和Survivor空间的占比是8:1。接下来咱们再来运行一下:
![](/assets/blank.gif)
而这些信息的输出其实是JVM的这个参数发挥着作用,如下:
![](/assets/blank.gif)
不信咱们将这个参数去掉再来运行:
![](/assets/blank.gif)
![](/assets/blank.gif)
果真就木有了,所以还是将该参数加回来。其实目前没有GC相关的日志出来,接下来再来创建一个新的字节数组:
![](/assets/blank.gif)
再运行:
/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/bin/java -verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -Dfile.encoding=UTF-8 -classpath /Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/deploy.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/ext/cldrdata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/ext/dnsns.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/ext/jaccess.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/ext/jfxrt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/ext/localedata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/ext/nashorn.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/ext/sunec.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/ext/zipfs.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/javaws.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/jfxswt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/management-agent.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/plugin.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/lib/ant-javafx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/lib/dt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/lib/javafx-mx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/lib/jconsole.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/lib/packager.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/lib/sa-jdi.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/lib/tools.jar:/Users/xiongwei/Documents/workspace/IntelliJSpace/jvm_lectue/out/production/classes:/Users/xiongwei/.gradle/caches/modules-2/files-2.1/mysql/mysql-connector-java/5.1.34/46deba4adbdb4967367b013cbc67b7f7373da60a/mysql-connector-java-5.1.34.jar:/Users/xiongwei/.gradle/caches/modules-2/files-2.1/cglib/cglib/3.2.0/bced5c83ed985c080a24dc5a42b0ca631556f413/cglib-3.2.0.jar:/Users/xiongwei/.gradle/caches/modules-2/files-2.1/org.ow2.asm/asm/5.0.3/dcc2193db20e19e1feca8b1240dbbc4e190824fa/asm-5.0.3.jar:/Users/xiongwei/.gradle/caches/modules-2/files-2.1/org.apache.ant/ant/1.9.4/6d473e8653d952045f550f4ef225a9591b79094a/ant-1.9.4.jar:/Users/xiongwei/.gradle/caches/modules-2/files-2.1/org.apache.ant/ant-launcher/1.9.4/334b62cb4be0432769679e8b94e83f8fd5ed395c/ant-launcher-1.9.4.jar com.jvm.gc.MyTest1
[GC (Allocation Failure) [PSYoungGen: 7167K->464K(9216K)] 7167K->6616K(19456K), 0.0060472 secs] [Times: user=0.01 sys=0.01, real=0.01 secs]
[Full GC (Ergonomics) [PSYoungGen: 464K->0K(9216K)] [ParOldGen: 6152K->6487K(10240K)] 6616K->6487K(19456K), [Metaspace: 2649K->2649K(1056768K)], 0.0048810 secs] [Times: user=0.01 sys=0.00, real=0.00 secs]
hello world
HeapPSYoungGen total 9216K, used 2290K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000)eden space 8192K, 27% used [0x00000007bf600000,0x00000007bf83c9a0,0x00000007bfe00000)from space 1024K, 0% used [0x00000007bfe00000,0x00000007bfe00000,0x00000007bff00000)to space 1024K, 0% used [0x00000007bff00000,0x00000007bff00000,0x00000007c0000000)ParOldGen total 10240K, used 6487K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000)object space 10240K, 63% used [0x00000007bec00000,0x00000007bf255d40,0x00000007bf600000)Metaspace used 2656K, capacity 4486K, committed 4864K, reserved 1056768Kclass space used 287K, capacity 386K, committed 512K, reserved 1048576KProcess finished with exit code 0
此时就出现了两种类型的GC,说明发生了GC操作,而这两种类型的GC其实在之前的理论学习中也提及过,回顾一下:
![](/assets/blank.gif)
接下来咱们再来修改程序:
![](/assets/blank.gif)
也就是说随着我们创建的字节的多少,其GC的输出也会不一样,接下来则对这些日志输出进行一个解答,了解它们能够更加深刻的理论GC相关的东东:
![](/assets/blank.gif)
![](/assets/blank.gif)
其实图中的疑问也来自于之前的理论学习,回顾下:
![](/assets/blank.gif)
也就是说对于咱们的新生代是采用PS收集器来进行垃圾回收的,接着继续往下分析:
![](/assets/blank.gif)
但是!!我在配置的JVM参数新生代的容量其实设置的是10M,如下:
![](/assets/blank.gif)
为啥我们在日志中看到的新生代总的容量只有9M呢?这里就还得回到新生代的空间组成了,它是由一个Eden空间和两个Survivor空间组成的,其中Survivor只会用一个,另一个会是空间进行数据交换用的,所以其总的新生代的大小就是Eden空间(8M)+1个Survivor空间(1M) = 9M。继续往下分析日志:
![](/assets/blank.gif)
为啥总的堆大小的容量是19M,而非我们指定的20M呢?
![](/assets/blank.gif)
还是因为年轻代总大小会少1M。往下继续:
![](/assets/blank.gif)
至此对于GC的日志就彻底了解了,对于FULL GC其实里面的含义也一样,接下来则是整个垃圾回收的汇总信息,分析一下:
![](/assets/blank.gif)
![](/assets/blank.gif)
最后咱们来计算一下这个老年代已使用了8K是如何得出来的?
![](/assets/blank.gif)
还得由之前的GC日志来得算,下面来算一下:
![](/assets/blank.gif)
这俩一相减就得出在新生代进行了gc之后所释放的容量为8191-464=7727,接着再来看一下总堆的释放情况:
![](/assets/blank.gif)
![](/assets/blank.gif)
那有个疑问:为啥总的堆空间释放的大小还不如新生代释放的大小呢?这里需要注意:对于新生代的释放其实分为两种:一是真正的被回收的,二是没有真正被回收,而是该对象进升到老年代了,而堆空间的释放值代表是真正被释放的大小。
那这俩数据之间有啥关系呢?其实这个关系是非常微妙的,为啥,看一下:“7727-7719=8k”,这不就是我们看到老年代已使用的大小么?
![](/assets/blank.gif)
所以新生代释放的大小-总堆释放的大小则就是从新生代进升到老年代的容量大小。
垃圾回收日志与算法深度解读相关推荐
- a*算法的优缺点_垃圾回收的常见算法
垃圾回收的常见算法 2.1 引用计数法 2.1.1 原理 2.1.2 优缺点 2.2 标记清除法 2.2.1 原理 2.2.2 优缺点 2.3 标记压缩算法 2.3.1 原理 2.3.2 优缺点 2. ...
- 一篇文章教你弄懂java CMS垃圾回收日志
文章目录 一.CMS垃圾回收器介绍 二.CMS JVM运行参数 三.CMS收集器运行过程 1.初始标记(CMS initial mark) 2.并发标记(CMS concurrent mark) 3. ...
- 万字长文教你看懂java G1垃圾回收日志
文章目录 一.如何在idea打印G1日志 二.G1基础参数 三.G1新生代收集 1. 四个关键信息 2. 列出了新生代收集中并行收集的详细过程 3.列出了新生代GC中的一些任务: 4.包含一些扩展功能 ...
- Java垃圾回收日志解析
1.开启垃圾回收日志 在运行一个java程序时可以在命令行中加入相应的JVM垃圾回收参数,获取程序运行时详细的垃圾回收日志信息.以下是一些大概的参数: -XX:+PrintGC与-verbose:gc ...
- GC:垃圾回收机制及算法
GC:垃圾回收机制及算法 关键词 算法:标记(清除/复制/整理).分代收集 收集器(Serial[串行].ParNew[并行].Parallel Scavenge[并行].Serial Old[串行] ...
- 【JVM】垃圾回收机制及算法
垃圾回收机制及算法 一.垃圾回收概述 二.对象是否存活 1. 判断对象是否存活 - 引用计数算法 2.判断对象是否存活-可达性分析算法 1.可达性分析算法 2.JVM之判断对象是否存活 3.关于引用 ...
- 想知道垃圾回收暂停的过程中发生了什么吗?查查垃圾回收日志就知道了!
\ 关键点 \ 垃圾回收日志中包括着一些关键性能指标: \ 要做一次正确的垃圾回收分析需要收集许多数据,所以好的工具是非常必要的: \ 除了垃圾回收之外还有很多事件都可能会让应用程序暂停: \ 让你的 ...
- idea本地跑如何看gc日志_不可思议,竟然还有人不会查看GC垃圾回收日志?
日志的重要性,不需要过多强调了.通过日志,我们可以发现程序可能有内存(泄露)问题.本文从案例出发,具体介绍这些日志信息,以期帮助大家更好地了解垃圾回收的运行情况. 还是先上图,看看本文的主要内容: 我 ...
- java知识点8——垃圾回收原理和算法、通用的分代垃圾回收机制、 JVM调优和Full GC、开发中容易造成内存泄露的操作
垃圾回收原理和算法 内存管理 Java的内存管理很大程度指的就是对象的管理,其中包括对象空间的分配和释放. 对象空间的分配:使用new关键字创建对象即可 对象空间的释放:将对象赋值null即可 垃圾回 ...
最新文章
- python画树叶-Python_Turtle库画一只派大星
- 运行python需要网吗-python搭建网站(想学Python有什么建议吗?)
- 如何安装最新版本的 SAP ABAP Development Tool ( ADT ) 2021年度更新
- java 事件通知_正确获取Java事件通知
- 使用python将excel数据导入数据库
- Django 时间与时区设置问题
- 每日一题(50)—— 各类型与零值的比较
- 淘宝直播上线“湖北加油”专区:近7000湖北商家获得扶持
- android10 三星升级计划,Android 10.0(Q OS)系统升级计划Androi
- ChengDu University Mental Health Test 需求分析文档
- css3弹性盒模型flex快速入门与上手(align-content与align-items)
- FastStone Capture—屏幕录像
- 独孤求败-小滴云架构大课十八式-xdclass2022
- linux双系统无u盘安装教程视频教程,window 与Linux Mint 双系统U盘安装方法
- 转 OpenGL核心技术之帧缓冲
- 步步高s5pro和s5区别
- 互联网中越老越吃香的行业是?
- 蓝牙路由器蓝牙点对多点组网蓝牙远程控制
- 微信小程序开发之大转盘 抽奖
- 服务器托管数据中心机房选择应该注意哪些事项