关于这一段代码 有几个不是让人很理解的地方,我一一说来。

1.Desired survivor size 524288 bytes

  关于这个512KB空间是怎么来的,JVM有这样一个参数:

  -XX:TargetSurvivorRatio:目标存活率,默认为50%,表明所有age的survivor space对象的大小如果超过Desired survivor size,则重新计算threshold,以age和MaxTenuringThreshold的最小值为准,否则以MaxTenuringThreshold为准.

  简单的说,如果要分配的Survivor空间是1M那么,desired survivor size 就是512KB,这个大小影响的是Tenuring Threshold参数

  当你试图放入800KB的对象是,Survivor from是运行你放入的,但是Tenuring Threshold大小会变成1(就算你之前是15,这里也会动态改成1),即下次GC发生时,age=1的统统放入老年代

2.Eden,Survivor from,to的关系

  对象分配空间的时候,若Eden仍有区域时,都会将对象放置Eden,持续新增对象一段时间后,Eden无法容纳时,这个时候就会发生一次Minor GC。

  当发生Minor GC时,会将Eden和 Survivor from中的幸存对象存放在Survivor to中,同时这些对象的age+1。

  若Survivor to无法容纳幸存对象,就将无法容纳的对象放置在永久带中。

  当GC时,存在对象的age=Tenuring Threshold时,不管Survivor to是否空间足够,都将他们放入永久代。

发生GC的前提,放入对象时空间不够,放入对象后空间占用完毕。


这段例子中,当XX:MaxTenuringThreshold=1时

a1 = 0.25M,a2=4M;

分配a3=4M时,Eden无法容纳4M的对象了,发起Minor GC,此时a1,a2 age=1,

这个时候,Survivor最大容量1M,无法同时容纳存活的4.5M a1,a2

虚拟机将4M的a2放入老年代,同时将0.25M的a1放入Survivor to中,此时空间分布Eden(0M),Survivor from(0.25M),Old(4M)

放入4M的a3,此时空间分布Eden(4M),Survivor from(0.25M),Old(4M)

a3=null;只是说明了a3无引用,但是数组空间仍然存在,只是提示jvm我下次可以被回收了

a3=4M,又分配了4M的空间,这个时候Eden 4+4=8M 已经满了,触发一次GC(这时,jvm会清理age=1的对象,a1,a2被放在了老年代)

发现之前创建的4M数组没有GC Root相关联,而且不符合自救规则,回收。

此时空间分布Eden(4M),Survivor from(0M),Old(4.25M)

/**
* VM参数:-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=1 -XX:+PrintTenuringDistribution
*
*/
@SuppressWarnings("unused")
public static void testTenuringThreshold() {
byte[] allocation1, allocation2, allocation3;
allocation1 = new byte[_1MB / 4]; //262144 什么时候进入老年代决定于XX:MaxTenuringThreshold设置
allocation2 = new byte[4 * _1MB]; //
allocation3 = new byte[4 * _1MB];
allocation3 = null;
allocation3 = new byte[4 * _1MB];
    /**
*
* XX:MaxTenuringThreshold=1
[GC [DefNew
Desired survivor size 524288 bytes, new threshold 1 (max 1)
- age 1: 418144 bytes, 418144 total
: 4695K->408K(9216K), 0.0054252 secs] 4695K->4504K(19456K), 0.0054708 secs] [Times: user=0.02 sys=0.00, real=0.01 secs]
[GC [DefNew
Desired survivor size 524288 bytes, new threshold 1 (max 1)
- age 1: 136 bytes, 136 total
: 4668K->0K(9216K), 0.0013601 secs] 8764K->4504K(19456K), 0.0013867 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
Heap
def new generation total 9216K, used 4260K [0x32750000, 0x33150000, 0x33150000)
eden space 8192K, 52% used [0x32750000, 0x32b78fe0, 0x32f50000)
from space 1024K, 0% used [0x32f50000, 0x32f50088, 0x33050000)
to space 1024K, 0% used [0x33050000, 0x33050000, 0x33150000)
tenured generation total 10240K, used 4504K [0x33150000, 0x33b50000, 0x33b50000)
the space 10240K, 43% used [0x33150000, 0x335b60a0, 0x335b6200, 0x33b50000)
compacting perm gen total 12288K, used 377K [0x33b50000, 0x34750000, 0x37b50000)
the space 12288K, 3% used [0x33b50000, 0x33bae5c0, 0x33bae600, 0x34750000)
ro space 10240K, 55% used [0x37b50000, 0x380d1140, 0x380d1200, 0x38550000)
rw space 12288K, 55% used [0x38550000, 0x38bf44c8, 0x38bf4600, 0x39150000)
*/
}

这段例子中,当XX:MaxTenuringThreshold=8时

a1 = 0.25M,a2=4M;

分配a3=4M时,Eden无法容纳4M的对象了,发起Minor GC

这个时候,Survivor最大容量1M,无法同时容纳存活的4.5M a1,a2

虚拟将4M的a2放入老年代,同时将0.25M的a1放入Survivor to中,此时空间分布Eden(0M),Survivor from(0.25M),Old(4M)

放入3M的a3,此时空间分布Eden(4M),Survivor from(0.25M),Old(4M)

a3=null;只是说明了a3无引用,但是数组空间仍然存在,只是提示jvm我下次可以被回收了

a3=4M,又分配了4M的空间,这个时候Eden 4+4=8M 已经满了,触发一次GC

发现之前创建的4M数组没有GC Root相关联,而且不符合自救规则,回收。

此时空间分布Eden(4M),Survivor from(0.25M),Old(4M)

/**
*
* XX:MaxTenuringThreshold =8
[GC [DefNew
Desired survivor size 524288 bytes, new threshold 8 (max 8)
- age 1: 418144 bytes, 418144 total
: 4695K->408K(9216K), 0.0036693 secs] 4695K->4504K(19456K), 0.0036983 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC [DefNew
Desired survivor size 524288 bytes, new threshold 8 (max 8)
- age 1: 136 bytes, 136 total
- age 2: 417936 bytes, 418072 total
: 4668K->408K(9216K), 0.0010034 secs] 8764K->4504K(19456K), 0.0010296 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
Heap
def new generation total 9216K, used 4668K [0x32750000, 0x33150000, 0x33150000)
eden space 8192K, 52% used [0x32750000, 0x32b78fe0, 0x32f50000)
from space 1024K, 39% used [0x32f50000, 0x32fb6118, 0x33050000)
to space 1024K, 0% used [0x33050000, 0x33050000, 0x33150000)
tenured generation total 10240K, used 4096K [0x33150000, 0x33b50000, 0x33b50000)
the space 10240K, 40% used [0x33150000, 0x33550010, 0x33550200, 0x33b50000)
compacting perm gen total 12288K, used 377K [0x33b50000, 0x34750000, 0x37b50000)
the space 12288K, 3% used [0x33b50000, 0x33bae5b8, 0x33bae600, 0x34750000)
ro space 10240K, 55% used [0x37b50000, 0x380d1140, 0x380d1200, 0x38550000)
rw space 12288K, 55% used [0x38550000, 0x38bf44c8, 0x38bf4600, 0x39150000)
*/

读《深入理解jvm虚拟机》之长期存活对象进入老年代,有感!!!!的更多相关文章

  1. 推荐收藏系列:一文理解JVM虚拟机(内存、垃圾回收、性能优化)解决面试中遇到问题(图解版)

    欢迎一起学习 <提升能力,涨薪可待篇> <面试知识,工作可待篇 > <实战演练,拒绝996篇 > 欢迎关注我博客 也欢迎关注公 众 号[Ccww笔记],原创技术文章 ...

  2. 深入理解JVM虚拟机10:JVM常用参数以及调优实践

    转自http://www.rowkey.me/blog/2016/11/02/java-profile/?hmsr=toutiao.io&utm_medium=toutiao.io&u ...

  3. 深入理解JVM虚拟机3:垃圾回收器详解

    JVM GC基本原理与GC算法 Java的内存分配与回收全部由JVM垃圾回收进程自动完成.与C语言不同,Java开发者不需要自己编写代码实现垃圾回收.这是Java深受大家欢迎的众多特性之一,能够帮助程 ...

  4. 《深入理解JVM虚拟机》读书笔记

    前言:<深入理解JVM虚拟机>是JAVA的经典著作之一,因为内容更偏向底层,所以之前一直没有好好的阅读过.最近因为刚好有空,又有了新目标.所以打算和<构架师的12项修炼>一起看 ...

  5. 进入JVM的世界:《深入理解JVM虚拟机》-- 思维导图

    进入JVM的世界:<深入理解JVM虚拟机>-- 思维导图 之前一直都是零零散散的看了些JVM的知识,心想这样不行啊!于是便抽空看了一下这本神书,阅罢,醍醐灌顶.豁然开朗.真正的是知其然,更 ...

  6. Java工程师学习指南第6部分:深入理解JVM虚拟机

    本文整理了微信公众号[Java技术江湖]发表和转载过的JVM虚拟机相关优质文章,想看到更多Java技术文章,就赶紧关注本公众号吧吧. JVM原理分析,看了都说好 JVM 深入学习:Java 解析 Cl ...

  7. 深入理解JVM虚拟机11:Java内存异常原理与实践

    本文转自互联网,侵删 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutori ...

  8. 深入理解JVM虚拟机1:JVM内存的结构与消失的永久代

    本文转自互联网,侵删 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutori ...

  9. JVM中的堆的新生代、老年代、永久代详解

    JVM中的堆一般分为三大部分:新生代.老年代.永久代,其大致的占比如下:  一.新生代 新生代主要用来存放新生的对象.一般占据堆空间的1/3.在新生代中,保存着大量的刚刚创建的对象,但是大部分的对象都 ...

随机推荐

  1. Quartz.NET持久化

    Quartz.NET所用到的数据库表结构 官方提供的各种数据库脚本:https://github.com/quartznet/quartznet/tree/master/database/tables ...

  2. Java 打印PDF文档的3种情况

    以下内容归纳了通过Java程序打印PDF文档时的3种情形.即: 静默打印 显示打印对话框打印 打印PDF时自定义纸张大小 使用工具:Spire.PDF for Java Jar导入: 方法1:通过官网 ...

  3. js重载的实现

    在JavaScript高级程序设计书中看到 ECMAScript函数中不能想传统意义上那样实现重载.而在其他语句中(Java)中,可以为一个函数编写两个定义,只要两个定义的签名(接受的参 数的类型和数 ...

  4. 前端js优化方案(一)

    最近在读<高性能javascript>,在这里记录一下读后的一些感受,顺便加上自己的一些理解,如果有兴趣的话可以关注的我的博客http://www.bloggeng.com/,我会不定期发 ...

  5. 如何下载Oracle E-Business Suite (12.2.6) for Microsoft Windows x64 (64-bit)

    下载地址:https://edelivery.oracle.com/ 使用您的 Oracle 账户进行登录.如果您没有该账户, 请注册 Oracle 账户.     Oracle Software D ...

  6. 送H-1B 及其他I-129 申请别忘用新表

    (梁勇律师事务所,lianglaw.com专稿)移民局从2010年11月23日 更新了申请H-1B 及其他非移民工作签证I-129 表,从2010年12月23日以后收到的I-129表都必须是2010年 ...

  7. pat甲级1020中序后序求层序

    1020 Tree Traversals (25)(25 分) Suppose that all the keys in a binary tree are distinct positive int ...

  8. linux 命令——46 vmstat(转)

    vmstat 是Virtual Meomory Statistics(虚拟内存统计)的缩写,可对操作系统的虚拟内存.进程.CPU活动进行监控.他是对系统的整体情况进行统计,不足之处是无法对某个进程进行 ...

  9. 撸了个 django 数据迁移工具 django-supertube

    撸了个 django 数据迁移工具 django-supertube 支持字段映射和动态字段转化. 欢迎 star,issue https://github.com/FingerLiu/django- ...

  10. innobackupex基于binlog日志的恢复 -- 使用mysqlbinlog恢复

    备份先做一次完整备份: innobackupex --defaults-file=/etc/my.cnf --user root --password chengce243 /data/mysqlba ...