无名 发表于 2022-5-8 17:46:44

【GD】Java堆内存的GC模型概述


这里怎挽,进来喝杯茶,听我慢慢讲[滑稽][茶杯]

      ————————————
       很高兴认识大家!
      ————————————
   ?【GD团队】:怎挽
      ————————————
      记得点赞,回复,关注
      ————————————
往期回顾
#【GD】C++的介绍,让你对C++的基础认识,学前必备!#
#【GD】编写C语言程序 输出一个菱形#
#【GD】Python 网络爬虫入门详解,以及爬虫模拟登陆!#
#【GD】Python 网络爬虫入门详解,以及爬虫模拟登陆!#
#【GD】JS实现QQ空间自动给好友点赞效果#http://cdn.u1.huluxia.com/g3/M02/4D/2E/wKgBOV6fBaOAA8hoAAKiGusY31I241.jpg
1JDK1.7的堆内存GC模型http://cdn.u1.huluxia.com/g3/M02/4D/2E/wKgBOV6fBaOAf2PZAAHIAJfpmgA692.jpg
1.1Young 年轻代
??Young中的大部分对象的生命都是短暂的,所以将内存分为一块较大的Eden和两块较小的大小严格相同的Survivor1、Survivor2,JVM默认分配是8:1:1(但是JVM默认开启Survivor区大小自动变化的参数,关闭即可。),其中,Survivor区间中,某一时刻只有其中一个是被使用的,另外一个留做垃圾收集时复制对象用。每次调用Eden和其中的Survivor1(FromSpace)。
??在GC开始的时候,对象只会存在于Eden区和名为“From”的Survivor区,Survivor区“To”是空的。在Eden区间变满的时候,触发Minor GC,Eden区中所有存活的对象都会被复制到“To”,而在“From”区中,仍存活的对象会根据他们的年龄值来决定去向。年龄达到一定值(年龄阈值,可以通过-XX:MaxTenuringThreshold来设置)的对象会被移动到年老代中,没有达到阈值的对象会被复制到“To”区域。经过这次GC后,Eden区和From区已经被清空。这个时候,“From”和“To”会交换他们的角色,也就是新的“To”就是上次GC前的“From”,新的“From”就是上次GC前的“To”。不管怎样,都会保证名为To的Survivor区域是空的。Minor GC会一直重复这样的过程,直到“To”区被填满,“To”区被填满之后,会将所有对象移动到年老代中。
1.2Tenured 老年代
??Tenured区主要保存生命周期长的对象,一般是一些老的对象,当一些对象在Young复制转移一定的次数以后(Minor GC),对象就会被转移到Tenured区,一般如果系统中用了application级别的缓存,缓存中的对象往往会被转移到这一区间。
??同理,当老年代中没有足够的内存空间来存放对象时,虚拟机会发起一次Major GC/Full GC。其实不论是Minor GC或者Major GC都存在这么一个问题,怎么处理跨代引用?因此通常Major都会回收年轻带。
??Serial,Parallel scavenge,Parallel old垃圾回收器回收老年代的时候还会回收年轻代,Major GC就是Full GC。
??CMS则是有两种模式,在没有设置-XX:+CMSScavengeBeforeRemark的时候,会扫描年轻代,但是只回收老年代,只有这个模式是真正的只进行Old GC;设置之后,会同时回收老年代和年轻代;
??G1比较特殊,它无论处于何种模式下,都不需要扫描别的代,只需要处理一下记忆集;
1.3Perm 永久代
??Perm Gen代主要保存class,method,filed对象,这部份的空间一般不会溢出,除非一次性加载了很多的类,不过在涉及到热部署的应用服务器的时候,有时候会遇到java.lang.OutOfMemoryError : PermGen space 的错误,造成这个错误的很大原因就有可能是每次都重新部署,但是重新部署后,类的class没有被卸载掉,这样就造成了大量的class对象保存在了perm中,这种情况下,一般重新启动应用服务器可以解决问题。

2 JDK1.8的堆内存模型http://cdn.u1.huluxia.com/g3/M02/4D/2E/wKgBOV6fBaSAaYehAAFgAF0-8ZQ300.jpg
由上图可以看出,JDK1.8的堆内存模型是由2部分组成,年轻代 + 年老代。

年轻代:Eden + 2*Survivor
年老代:Old Gen

??在JDK1.8中变化最大的Perm区,用Metaspace(元数据空间)进行了替换。需要特别说明的是:Metaspace所占用的内存空间不是在虚拟机内部,而是在本地内存空间中,这也是与1.7的永久代最大的区别所在。
——————————http://cdn.u1.huluxia.com/g3/M02/4D/2E/wKgBOV6fBaWAGTA9AAEn8pW9Yu8992.jpg
剩下楼层更新!
页: [1]
查看完整版本: 【GD】Java堆内存的GC模型概述