• godtrue 置顶
    2018-08-21
    写的非常棒,又帮我看到了一个小黑盒中的天地。
    小结:
    1:二八法则-适用于许多的领域,对象在JVM对内存空间的生命周期也同样符合

    2:为了更好的JVM性能以及充分利用对象生命周期的二八法则,JVM的作者将JVM的对内存空间进行了分代的处理

    3:堆内存空间=年轻代+老年代

        年轻代=Eden+from+to
        年轻代用于分配新生的对象
        Eden-通常用于存储新创建的对象,对内存空间是共享的,所以,直接在这里面划分空间需要进行同步
         from-当Eden区的空间耗尽时,JVM便会出发一次Minor GC 来收集新生代的垃圾,会把存活下来的对象放入Survivor区,也就是from区
    注意,from和to是变动的
          to-指向的Survivor区是空的,用于当发生Minor GC 时,存储Eden和from区中的存活对象,然后再交换from和to指针,以保证下一次Minor GC 时to指向的Survivor区还是空的。

          老年代-用于存储存活时间更久的对象,比如:15次Minor GC 还存活的对象就放入老年代中

    4:堆内存分代后,会根据他们的不同特点来区别对待,进行垃圾回收的时候会使用不同的垃圾回收方式,针对新生代的垃圾回收器有如下三个:Serial、Parallel Scavenge、Parallel New,他们采用的都是标记-复制的垃圾回收算法。
    针对老年代的垃圾回收器有如下三个:Serial Old 、Parallel Old 、CMS,他们使用的都是标记-压缩的垃圾回收算法。

    5:TLAB(Thread Local Allocation Buffer)-这个技术是用于解决多线程竞争堆内存分配问题的,核心原理是对分配一些连续的内存空间

    6:卡表-这个技术是用于解决减少老年代的全堆空间扫描
    展开

    作者回复: 好长的总结,赞一个

     1
     27
  • 公子_小白
    2018-08-23
    老师您好
    请问JVM分代收集新生代对象进入老年代,年龄为什么是15而不是其他的?
    谢谢

    作者回复: HotSpot会在对象头中的标记字段里记录年龄,分配到的空间只有4位,最多只能记录到15

    
     18
  •  素丶  
    2018-11-20
    可以配合R大的文章
    http://rednaxelafx.iteye.com/blog/1042471
    http://rednaxelafx.iteye.com/blog/174865
    http://rednaxelafx.iteye.com/blog/1044951
    
     13
  • javaadu
    2018-08-17
    写得真好,搞清楚了之前没掌握透彻的概念:
    (1)TLAB是为了避免对象分配时对内存的竞争
    (2)卡表是为了处理minor gc时老年代对新生代的引用,为了避免整堆扫描而提出了卡表的概念

    提个问题:JVM中堆内存根系统的物理内存是如何对应的,这个可以从哪里看?

    作者回复: 根系统指的是?

    GC roots分布在HotSpot中的每个子系统里。可以在源码中搜oops_do

    
     8
  • herome
    2018-08-19
    老师 建议是能画点图吗 😂 每一篇都是文字。 相信画了图 不仅能让文章通俗易懂,也能让老师的文笔更好。

    作者回复: 多谢建议!

     1
     6
  • 愤怒的虾干
    2019-02-19
    1、当默认开启动态分配时,若ALIVE_OBJECT_SIZE小于33M几乎无FULL GC,大于则出现FULL GC。动态分配时Eden区大小不能小于Survivor区,即最少为新生代内存的1/3,单个Survivor区最大为新生代内存的1/3。故当ALIVE_OBJECT_SIZE大于33M时,Survivor区小于ALIVE_OBJECT_SIZE,导致Minor GC时需要复制到to区的数据大于to区容量,从而使得一部分数据提前晋升到老年区,多次提前晋升导致老年区无多余空间从而导致Full GC;当ALIVE_OBJECT_SIZE小于33M时,Survivor区容量总是近似的接近ALIVE_OBJECT_SIZE大小,使得每次Minor GC有效对象都可以复制到Survivor区,而晋升到老年代的对象大多是年龄达到次数要求,短期内不会挤满老年代空间,在有限时间内运行结束不会引发Full GC。
    2、当-XX:-UsePSAdaptiveSurvivorSizePolicy or -XX:SurvivorRatio=N关闭动态分配或指定Eden、Survivor比例时,只要ALIVE_OBJECT_SIZE小于Survivor容量,有限时间运行结束不会引发Full GC。反之会导致Full GC。
    @郑老师 是否是这样?
    展开
     1
     3
  • 西兹兹
    2019-01-19
    老师好,请问java8开始之后的元数据区的回收是如何呢?这部分属于堆外内存吗?
     1
     3
  • 公子_小白
    2018-08-24
    多谢老师的回复
    
     2
  • Ben
    2019-12-23
    老师,有个疑问想请教一下:
    如果Eden区和from指向的Survivor区存活对象大于to指向的Survivor区的大小,那么JVM会如何处理?

    作者回复: 会按对象年龄晋升最老的那些至老年代。极端情况,假设survivor 区大小为0,那就是直接把eden区的存活对象晋升过去了

    
     1
  • 必然
    2019-09-10
    郑老师,你好!
    我想请教一个CMS收集器的问题,就是 CMS 在“重新标记”结束后,在进入“并发清除”时,这时候GC线程和应用线程同时在跑,如果在GC线程清理“垃圾”的时候,应用线程又将“垃圾”恢复为正常对象,怎么办呢?
    会出现这种情况吗?是虚拟机采用了某种方式杜绝了这种情况的发生么?还是有什么其它处理机制呢?
    谢谢!
     1
     1
  • river
    2019-09-09
    总结与实践中的代码ObjectOf64Bytes的64=6*8(6个long类型字段)+16(该对象的对象头大小,不是说压缩后是12字节么?)
    
     1
  • JackJin
    2019-08-27
    当发生 Minor GC 时,Eden 区和 from 指向的 Survivor 区中的存活对象会被复制到 to 指向的 Survivor 区中,然后交换 from 和 to 指针,以保证下一次 Minor GC 时,to 指向的 Survivor 区还是空的。
    这里的交换指针不理解,仅仅只是让to区每次都是空的?
     2
     1
  • Dd
    2019-06-30
    郑老师好,对于针对新生代的垃圾回收器共有三个:Serial,Parallel Scavenge 和 Parallel New。这三个采用的都是标记 - 复制算法,其中Serial GC,新生代使用标记复制算法这个说法,有官方出处吗?因为我先看的官方说明地址如下(JDK1.7)https://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html,按照文档的定义
    Young Generation对应minor garbage collection,Old Generation对应major garbage collection

    然后在The Serial GC 收集器的说明中,有如下描述

    1.The serial collector is the default for client style machines in Java SE 5 and 6. With the serial collector, (both minor and major garbage collections are done serially) (using a single virtual CPU). In addition, it uses (a mark-compact) collection method

    对于Serial,算法到底是mark-compact 还是还是mark-copy?或者不同年代,还区分不同算法来进行垃圾收集?
    展开
    
     1
  • luffyke
    2019-06-25
    如果新生代晋升到老年代失败的时候如何处理?(可能原因:老年代内存不够,老年代碎片过多,晋升的新生代太大)
    
     1
  • Hamlin
    2019-05-29
    “当完成所有脏卡的扫描之后,Java 虚拟机便会将所有脏卡的标识位清零。”
    如果全部清零的话,下一次扫描时怎么知道该扫描哪些老年带区域?主要是指上一次遗留下的从老年带对新生代的引用。
    
     1
  • 多巴胺老邮差
    2018-12-20
    郑老师您好 ! 一直想问问CMS收集器中并发标记这一个步骤的作用是什么 ? 为什么还要在初始标记的基础上多进行一次Roots Tracing呢? 希望您能有空能够回复下 thx
    
     1
  • 骑车吃火锅
    2018-12-11
    请问老师,java类是如何被卸载的?
    
     1
  • Leon Wong
    2018-09-12
    老师你好,写屏障不会判断引用是否指向新生代的对象,这里会不会提高MinorGC的成本呢?
    
     1
  • 永烁星光
    2018-08-21
    这里老年代对象存在对新生代对象的引用,那么这个指的引用是栈里存储的reference 吗? 还是对象内的引用

    作者回复: 对象内的引用

    
     1
  • 侯金彪
    2018-08-18
    看某些资料介绍说tlab是将对象创建在栈内存上,并且与逃逸分析一起用,这样在释放栈内存时就直接将这部分内存一起释放了,降低了gc成本。您讲解的说tlab是提前在堆内存中分配空间,这样没有降低gc成本呀!

    作者回复: HotSpot不支持在栈上新建对象。

    C2里的逃逸分析是静态分析,和TLAB没什么关系。它和标量替换一起使用,能够完全不分配对象,仅在寄存器中维护这个对象的字段。

    
     1
我们在线,来聊聊吧