经过前面对于JVM垃圾回收学习了纯理论相关的东东,这次则要开始用代码编写大量的实验来对理论进行佐证,下面开始,先在IntelliJ IDEA工程中新建一个全新的包:

然后新建一个类:

接下来则会编写一个超级简单的程序,程序虽简单,但是通过增加一些JVM的参数可以用简单的程序来阐述JVM垃圾回收的很多知识点,所以意义还是挺大的,具体如下:

哇,确实是简单,但是这里有个注意点:就是对于这个byte类型的数组其实里面存放的是为0的原生类型,可以打印看一下:

而如果是引用类型的数组则里面每个存放的是null,需要明白,接下来多创建几个byte数组:

目前来看这是一个非常非常之low的程序,但是如果咱们给JVM增加一些运行参数,再输出看到的东东则会大不一样,下面来增加一些启动参数:

这里有意将堆空间设置得较小以便可以供咱们观察GC的情况,继续:

还有最后一个参数:

这代表啥意思呢?其实它代表新生代的比例,如之前理论所介绍:

也就是这里的配置就代表新生代的区域是8:1:1,也就是Eden空间和Survivor空间的占比是8:1。接下来咱们再来运行一下:

而这些信息的输出其实是JVM的这个参数发挥着作用,如下:

不信咱们将这个参数去掉再来运行:

果真就木有了,所以还是将该参数加回来。其实目前没有GC相关的日志出来,接下来再来创建一个新的字节数组:

再运行:

/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其实在之前的理论学习中也提及过,回顾一下:

接下来咱们再来修改程序:

也就是说随着我们创建的字节的多少,其GC的输出也会不一样,接下来则对这些日志输出进行一个解答,了解它们能够更加深刻的理论GC相关的东东:

其实图中的疑问也来自于之前的理论学习,回顾下:

也就是说对于咱们的新生代是采用PS收集器来进行垃圾回收的,接着继续往下分析:

但是!!我在配置的JVM参数新生代的容量其实设置的是10M,如下:

为啥我们在日志中看到的新生代总的容量只有9M呢?这里就还得回到新生代的空间组成了,它是由一个Eden空间和两个Survivor空间组成的,其中Survivor只会用一个,另一个会是空间进行数据交换用的,所以其总的新生代的大小就是Eden空间(8M)+1个Survivor空间(1M) = 9M。继续往下分析日志:

为啥总的堆大小的容量是19M,而非我们指定的20M呢?

还是因为年轻代总大小会少1M。往下继续:

至此对于GC的日志就彻底了解了,对于FULL GC其实里面的含义也一样,接下来则是整个垃圾回收的汇总信息,分析一下:

最后咱们来计算一下这个老年代已使用了8K是如何得出来的?

还得由之前的GC日志来得算,下面来算一下:

这俩一相减就得出在新生代进行了gc之后所释放的容量为8191-464=7727,接着再来看一下总堆的释放情况:

那有个疑问:为啥总的堆空间释放的大小还不如新生代释放的大小呢?这里需要注意:对于新生代的释放其实分为两种:一是真正的被回收的,二是没有真正被回收,而是该对象进升到老年代了,而堆空间的释放值代表是真正被释放的大小。

那这俩数据之间有啥关系呢?其实这个关系是非常微妙的,为啥,看一下:“7727-7719=8k”,这不就是我们看到老年代已使用的大小么?

所以新生代释放的大小-总堆释放的大小则就是从新生代进升到老年代的容量大小。

垃圾回收日志与算法深度解读相关推荐

  1. 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. ...

  2. 一篇文章教你弄懂java CMS垃圾回收日志

    文章目录 一.CMS垃圾回收器介绍 二.CMS JVM运行参数 三.CMS收集器运行过程 1.初始标记(CMS initial mark) 2.并发标记(CMS concurrent mark) 3. ...

  3. 万字长文教你看懂java G1垃圾回收日志

    文章目录 一.如何在idea打印G1日志 二.G1基础参数 三.G1新生代收集 1. 四个关键信息 2. 列出了新生代收集中并行收集的详细过程 3.列出了新生代GC中的一些任务: 4.包含一些扩展功能 ...

  4. Java垃圾回收日志解析

    1.开启垃圾回收日志 在运行一个java程序时可以在命令行中加入相应的JVM垃圾回收参数,获取程序运行时详细的垃圾回收日志信息.以下是一些大概的参数: -XX:+PrintGC与-verbose:gc ...

  5. GC:垃圾回收机制及算法

    GC:垃圾回收机制及算法 关键词 算法:标记(清除/复制/整理).分代收集 收集器(Serial[串行].ParNew[并行].Parallel Scavenge[并行].Serial Old[串行] ...

  6. 【JVM】垃圾回收机制及算法

    垃圾回收机制及算法 一.垃圾回收概述 二.对象是否存活 1. 判断对象是否存活 - 引用计数算法 2.判断对象是否存活-可达性分析算法 1.可达性分析算法 2.JVM之判断对象是否存活 3.关于引用 ...

  7. 想知道垃圾回收暂停的过程中发生了什么吗?查查垃圾回收日志就知道了!

    \ 关键点 \ 垃圾回收日志中包括着一些关键性能指标: \ 要做一次正确的垃圾回收分析需要收集许多数据,所以好的工具是非常必要的: \ 除了垃圾回收之外还有很多事件都可能会让应用程序暂停: \ 让你的 ...

  8. idea本地跑如何看gc日志_不可思议,竟然还有人不会查看GC垃圾回收日志?

    日志的重要性,不需要过多强调了.通过日志,我们可以发现程序可能有内存(泄露)问题.本文从案例出发,具体介绍这些日志信息,以期帮助大家更好地了解垃圾回收的运行情况. 还是先上图,看看本文的主要内容: 我 ...

  9. java知识点8——垃圾回收原理和算法、通用的分代垃圾回收机制、 JVM调优和Full GC、开发中容易造成内存泄露的操作

    垃圾回收原理和算法 内存管理 Java的内存管理很大程度指的就是对象的管理,其中包括对象空间的分配和释放. 对象空间的分配:使用new关键字创建对象即可 对象空间的释放:将对象赋值null即可 垃圾回 ...

最新文章

  1. python画树叶-Python_Turtle库画一只派大星
  2. 运行python需要网吗-python搭建网站(想学Python有什么建议吗?)
  3. 如何安装最新版本的 SAP ABAP Development Tool ( ADT ) 2021年度更新
  4. java 事件通知_正确获取Java事件通知
  5. 使用python将excel数据导入数据库
  6. Django 时间与时区设置问题
  7. 每日一题(50)—— 各类型与零值的比较
  8. 淘宝直播上线“湖北加油”专区:近7000湖北商家获得扶持
  9. android10 三星升级计划,Android 10.0(Q OS)系统升级计划Androi
  10. ChengDu University Mental Health Test 需求分析文档
  11. css3弹性盒模型flex快速入门与上手(align-content与align-items)
  12. FastStone Capture—屏幕录像
  13. 独孤求败-小滴云架构大课十八式-xdclass2022
  14. linux双系统无u盘安装教程视频教程,window 与Linux Mint 双系统U盘安装方法
  15. 转 OpenGL核心技术之帧缓冲
  16. 步步高s5pro和s5区别
  17. 互联网中越老越吃香的行业是?
  18. 蓝牙路由器蓝牙点对多点组网蓝牙远程控制
  19. 微信小程序开发之大转盘 抽奖
  20. 服务器托管数据中心机房选择应该注意哪些事项

热门文章

  1. 从官网下载的mysql.zip如何使用
  2. python产生随机数序列_python产生随机数
  3. 徽章系列2:JitPack 的使用
  4. 通过Boomerang按计划在Gmail中发送或接收电子邮件(并且我们有邀请)
  5. bean标签的常用属性
  6. android action bar 风格,Android ActionBar使用教程
  7. linux 查看文件大小命令
  8. 【博物纳新】Isaura—光环特效开源库评测
  9. OutLook客户端删除邮件服务器邮件的恢复一例
  10. 暴力破解———罗马数字逆向解法,猜年龄利用位数信息,罗马数字的枚举解法