Java运行时内存工作过程

介绍在Java8中,运行时内存是如何工作的,对象的走向如何,Java7和Java8内存模型的变化又是什么?接下来让我给你解开谜团

运行时内存

基本组成如图:在这里插入图片描述

其中新生代又分为Eden区、SurvivorFrom、SurvivorTo三个区,这么分的目的是因为年轻代采用的是复制算法进行垃圾回收。

年轻代

在这里插入图片描述

  1. Eden区:Java新对象都在这里(如果新对象的内存占用很大,则直接分配到老年代)。当Eden区内存不够时会触发Minor GC(新生代垃圾回收),对新生代区进行一次垃圾回收
  2. SurvivorFrom:因为复制算法需要将一个内存区域分为两半,From是其中一半,垃圾回收时会扫描SurvivorFrom区,查看是否有年龄超过15的对象,超过15(默认值,可以通过-XX:MaxTenuringThreshold来设置)的对象进入老年代,年龄小于15的进入SurvivorTo区,对象年龄+1
  3. SurvivorTo:保留一次Minor GC过程中的幸存者

工作过程

  1. Minor GC开始,把Eden和Survivor区域中存活的对象复制到SurvivorTo区(年龄超过15的进入老年代区),同时对这些对象的年龄+1(如果SurvivorTo不够位置了就放到老年代区)
  2. 复制完成后,清空Eden、SurvivorFrom区中的对象
  3. 最后,SurvivorTo和SurvivorFrom互换,原来的SurvivorTo成为下一次Minor GC的SurvivorFrom区

老年代

主要存放对象在应用程序中生命周期长的内存对象
老年代对象不会像年轻代一样,朝生夕死,相对来说比较稳定,所有MajorGC不会频繁执行
有以下几种情况会触发MajorGC:

  1. 老年代空间不够用时触发
  2. 大对象进入老年代,没有连续空间分配给大对象会提前触发一次MajorGC进行垃圾回收腾出空间存放大对象
  3. 对MinorGC后晋升到老年代的大小大于老年代剩余的空间触发
  4. 手动调用System.gc(),建议触发Full GC

元数据区(Metaspace)

在java8之前,叫做永久区,由于其内存大小受限于java堆内存,随者Class的增多很容易触发OOM,因此在java8中做了调整,Metaspace位于本地堆内存(native heap),OOM问题不复存在,默认元数据区内存大小只受本地内存大小的限制,也就是说本地内存多大,Metaspace就可以有多大

元空间的出现就是为了解决突出的类和类加载器元数据过多导致的OOM问题

PermGen与Metaspace的对比:

PermGen(老年代)Metaspace(元数据区)
它已从Java 8中删除它是在Java 8中引入的
静态变量和常量池在方法去常量池、静态成员变量等迁移到了堆中
PermGen始终具有固定的最大大小默认情况下,元空间会根据基础操作系统自动增加其大小
连续的Java堆内存本地内存(由底层操作系统提供)
没有效率的垃圾收集高效的垃圾收集

在这里插入图片描述

有什么问题欢迎大家指正~~~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我思知我在

原创不易,多多一键三连

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值