JVM(三):HotSpot GC内存模型

        HotSpot中的大多数垃圾收集器,都遵循对象分代原则,而除了G1收集器使用的动态分代管理之外,其它的垃圾收集器都将java堆内存划分为固定比例大小的年轻代或老年代,不同的收集器采用相同的内存模型,将使得不同的收集器之间能够相互配合,达到更好的垃圾收集效果。本文将介绍HotSpot中大部分垃圾收集器所使用的内存模型。

方法区

        方法区保存着被加载过的每个类的信息以及相关的静态变量。HotSpot的方法区同样存在垃圾收集,对长时间未使用的元数据进行清理。

        对方法区进行垃圾回收的性价比通常是比较低的,在新生代中,通常一次垃圾收集可以回收70%至99%的内存空间,相比之下,方法区回收判定条件苛刻,垃圾收集的回收成果较低。

        方法区的垃圾收集主要分为:废弃的常量和不再使用的类型。与对象回收类似,当一个常量不存在引用时,既可以对其进行回收操作。而判断一个类型是否属于“不再使用的类”条件十分苛刻,需要满足:该类型所有的实例已经回收;加载该类的类加载器已经回收;该类型对应 java.lang.Class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。

      在jdk7之前,HotSpot将方法区划分为永久代,在jdk8之后,HotSpot永久移除了永久代的概念,将方法区区域划分为元空间。

        永久代(PermGen)

        在jdk8时,HotSpot移除了永久代的概念。永久代也是在堆内存中保存的,但是永远不会被回收。例如intern()方法产生的对象不会被回收。在此之前,如果操作不当,导致永久代中数据量过大,就会发生OutOfMemoryError。

        永久代会为GC带来不必要的复杂性,并且回收效率偏低,在永久代中元数据可能会随着每一次赋GC发生而进行移动,而HotSpot虚拟机每种类型的垃圾回收器都要特殊处理永久代中的元数据,分离出来以后可以简化赋GC,以及以后并发隔离元数据等方面进行优化。

        元空间

        jdk1.8新增的空间,功能和永久代类似,都是jvm方法区的实现之一,区别是永久代使用JVM的堆内存,而元空间使用的是物理机内存,默认情况下,元空间的大小直接受到本机的物理内存限制。

java堆

        HotSpot中将Java堆内存划分为新生代和老年代。

        新生代

        IBM公司曾有一项专门研究对于新生代“朝生夕灭”的特点做了更量化的诠释:新生代中的对象有98%存活不过一轮收集。因为在新生代中绝大多数的对象都是“朝生夕灭”,所以不需要按照1:1的比例来划分新生代的内存空间,而是分为三个部分,一块为Eden(伊面区)和两块较小的Survivor(幸存区)空间。只有10%的内存是浪费的。该内存分配回收方式称为Appel式回收。HotSpot中的Serial、ParNew等新生代收集器均采用的这种策略来设计新生代的内存布局。

        HotSpot将新生代中的内存划分为一块较大的Eden区和两块较小的Survivor区,官方推荐Eden:Survivor:Survivor比例为8:1:1。每次分配内存只使用Eden和其中一块Survivor,发生垃圾收集时,将Eden和Survivor中仍然存活的对象一次性复制到另外一块Survivor中,然后直接清理掉Eden和已经使用过的Survivor,新生代就可以使用90%的内存。

        但是Appel式回收仅仅是根据统计得出的普遍结论,适合大部分的应用程序,但是不能保证每次新生代都少于10%的对象存活,当在垃圾回收复制时候如果一块Survivor不够时候,需要老年代来分担,大对象直接进入老年代

        老年代

        老年代中的对象,大部分都是会继续长期存活的对象,相比于新生代,老年代不需要频繁的进行GC操作,并且每次进行垃圾回收,仅能回收较为有限的内存空间。但是也存在一些例外,当新生代中存活的对象超过一定的比例,用于复制的Survivor区域存放不下时,就会将大对象直接复制到老年代当中。

补充

        分代理论在实现的时候,存在一个十分棘手的问题,即不同对象之间存在跨代引用,如果在进行部分区域的内存回收时,却要遍历堆中的所有对象,那么效率未免过低,因此HotSpot中采用记忆集标识堆中可能存在的跨代引用。此后当发生Minor GC时,只有包含了跨代引用的小块内存里的对象才会被加入GC Roots进行扫描。该区域需要随时维护记录数据的正确性,会增加一些运行时开销,但是比起扫描整个堆来说仍然是划算的。

        java中的引用类型

引用类型被回收时间用途生存时间
强引用从来不会对象的一般状态JVM停止运行时
软引用内存不足时对象缓存内存不足时
弱引用jvm垃圾回收时对象缓存gc运行后
虚引用未知未知未知
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值