JVM(二)JVM的堆分代

前言

      本章讲解JVM的堆分代策略

方法

1.概念

通过上一章的说明我们可以知道,几乎所有的Java对象实例都放在Java堆中。

这也就意味着,堆中对象分配和回收将是JVM的处理重点!为了更好的处理这些对象,JVM便将Java堆分成几块区域。由于根据对象存活的周期不同,所以称之为新生代、老年代和永久代(JDK1.8起被移除

顾名思义,新生代存储的是年轻对象,老年代是稍微老一点的对象,永久代是老的不能再老的对象,哈哈哈

在JDK7以及其前期的JDK版本中,Java堆通常被分为三块区域年轻代(young 

generation)、老年代(old generation)、永久代(permanent generation),其中,年轻代中又划分了Eden区、Survivor0、Survivor1区。显示如下图:

这里需要澄清一个问题:方法区和永久代区别和联系

在JDK1.7以前,方法区位于永久代,我们可以说永久代是方法区的一种实现方式,也就是说我们平时称之为永久代的东西实际上就是方法区,永久代和堆相互隔离,但是是堆的逻辑组成部分,永久代的大小在启动JVM时可以设置一个固定值,不可变

在JDK1.7,存储在永久代的部分数据就已经转移到Java 堆或者直接内存。但永久代仍存在于JDK 1.7中,并没有完全移除,譬如符号引用(Symbols)转移到了直接内存;字符串常量池(interned strings)转移到了Java 堆;类的静态变量(class statics variables )转移到了Java 堆

在JDK1.8,仍然保留方法区的概念,只不过实现方式不同。取消永久代,方法存放于元空间(Metaspace),元空间仍然与堆不相连,但存在于直接内存中,逻辑上可认为在堆中。

 

一个对象在Java堆中的生活一般为下面步骤:

  • 1)所有新生成的对象首先都是放在年轻代的。年轻代的目标就是尽可能快速的收集掉那些生命周期短的对象。
  • 2)新生代内存按照8:1:1的比例分为一个eden区和两个survivor(survivor0,survivor1)区。大部分对象在Eden区中生成。回收时先将eden区存活对象复制到一个survivor0区,然后清空eden区,当这个survivor0区也存放满了时,则将eden区和survivor0区存活对象复制到另一个survivor1区,然后清空eden和这个survivor0区,此时survivor0区是空的,然后将survivor0区和survivor1区交换,即保持survivor1区为空, 如此往复。
  • 3)当survivor1区不足以存放 eden和survivor0的存活对象时,就将存活对象直接存放到老年代。若是老年代也满了就会触发一次Full GC,也就是新生代、老年代都进行回收。
  • 4)新生代发生的GC也叫做Minor GC,MinorGC发生频率比较高(不一定等Eden区满了才触发)

 

在JDK1.8,由于对永久代的调优过程非常困难,永久代的大小很难确定,所以JDK1.8取消了永久代的概念,转而叫元空间,因为其使用堆外内存,也就是直接内存,元空间的最大可分配空间就是系统可用内存空间可以避免永久代的内存溢出问题

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值