JVM---运行时的内存

整体堆结构

JVM运行时的内存也叫JVM堆,从GC的角度可以将JVM对分为新生代,老年代和永久代。其中新生代默认占1/3的空间,老年代默认占2/3的堆存储空间,永久代占非常少的空间。新生代又分为Eden区、SurvirorFrom区和SurvirorTo区,Eden默认占8/10的新生代空间,SurvirorFrom区和SurvirorTo区分别默认占1/10新生代空间,具体结构如下
在这里插入图片描述
下面分别讨论关于不同区域。

新生代

JVM创建的对象会存放在新生代,默认占据1/3的堆内存空间。由于JVM会频繁的创建对象,所以新生代会频繁的触发MinorGC(YGC)进行垃圾回收。新生代分为Eden区,SurvirorFrom区和SurvirorTo区
(1)Eden区:java新创建的对象首先会放在Eden区,如果创建的对象属于大对象,则直接将其分配到老年代。大对象的定义与具体的JVM版本、堆大小和垃圾回收策略有关,一般是2KB-12KB,可以通过XX:PartenureSize Threshold设置其大小。在Eden区空间不足的时候会触发YGC,对新生代进行垃圾回收。
(2)SurvirorTo区:保留上一次MinorGC时的幸存者。
(3)SurvirorFrom区:上一次MinorGC的幸存者作为这一次的被扫描者。
新生代的GC叫MinorGC,采用复制算法实现,具体实现过程如下:
(1)在Eden区和SurvirorFrom区存活的对象复制到SurvirorTo区。如果其年龄达到老年代的标准,则将其复制到老年代,同时把这些对象的年龄加一;空间不够或者属于大对象也复制到老年代;
(2)清空Eden区和SurvirorFrom区;
(3)将SurvirorFrom区与SurvirorTo区相互转换,原来的SurvirorTo区成为下一次的SurvirorFrom区。

老年代

老年代主要存放长生命周期的对象和大对象。老年代的GC叫做MajorGC(FGC),在进行MajorGc之前,JVM会进行一次MajorGC,在MajorGC过后仍然出现老年代且老年代空间不足或者无法找到足够大的连续空间分配给大对象的时候,会触发MajorGC进行垃圾回收,释放JVM的内存空间。
MajorGC采用的是标记清楚算法,该算法会扫面所有对象并且标记存活对象,然后回收未被标记的对象,并释放内存空间。这样也会产生扫描耗时间比较长,MajorGC的标记清楚算法容易产生内存碎片,会抛出Out Of Memory异常。

元数据区(永久代)

永久保存的区域,主要存放Class和Meta(元数据)的信息。Class被加载的时候被存放在元数据区。GC不会在此区域进行清理,这也导致永久代的内存会随着加载Class文件的增加而增加,在加载Class文件过多的时候也会产生Out Of Memory 异常,比如tomcat引用jar文件过多会导致JVM内存不足而无法启动。
需要注意的是在jdk1.8之后,元数据区不再存放在虚拟机的内存之中,而是存放在操作系统的本地内存中,因此元数据区不再受JVM的内存限制,只和操作系统的内存相关。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值