JVM内存模型

1、jvm内存模型、分区

  1. 程序计数器:记录当前线程执行的位置
  2. 方法区:用于储存已被虚拟机加载的类信息,常量池(常量,静态变量),即时编译器编译后的代码
  3. 堆:存放数组和对象实例
  4. 栈:定义基本数据类型的变量,一个对象的引用保存在栈里面

    Book b = new Book();
    new Book()实例是放到堆里面的
    b引用是放到栈里面的

2、堆分区

  • Java 堆从 GC 的角度细分为: 新生代(Eden 区、From Survivor 区和 To Survivor 区)和老年代。
  • 新生代:用来存放新生的对象,一般占据堆的1/3空间,由于频繁创建对象,所以新生代会触发gc进行垃圾回收,新生代分为Eden,servivorTo,servivorFrom区
  • Eden区:java新对象的出生地(新创建的对象占用内存很大,直接分配到老年代,当Eden区内存不够时就会触发gc,新生代进行一次垃圾gc)
  • servivorTo:上次gc的幸存者,作为这次gc的被扫描者
  • servivorFrom:保留一次gc过程的幸存者

新生代(MinorGC 采用复制算法)(复制->清空->互换)(存活对象少、垃圾多)
1.eden、servicorFrom 复制到 ServicorTo,年龄+1
首先,把 Eden 和 ServivorFrom 区域中存活的对象复制到 ServicorTo 区域
(如果有对象的年龄以及达到了老年的标准,则赋值到老年代区),
同时把这些对象的年龄+1(如果 ServicorTo 不够位置了就放到老年区);
2.清空 eden、servicorFrom
然后,清空 Eden 和 ServicorFrom 中的对象;
3.ServicorTo 和 ServicorFrom 互换
最后,ServicorTo 和 ServicorFrom 互换,原 ServicorTo 成为下一次 GC 时的 ServicorFrom区

老年代(MajorGC 采用标记清除算法)(标记整理)(存活对象多、垃圾少)
主要存放应用程序中生命周期长的内存对象
MajorGC 采用标记清除算法:
首先扫描一次所有老年代,标记出存活的对象,然后回收没有标记的对象。
MajorGC 的耗时比较长,因为要扫描再回收。
MajorGC 会产生内存碎片,为了减少内存损耗
我们一般需要进行合并或者标记出来方便下次直接分配(标记整理)。

永久代
指内存的永久保存区域,主要存放 Class 和 Meta(元数据)的信息,Class 在被加载的时候被放入永久区域
它和和存放实例的区域不同,GC 不会在主程序运行期对永久区域进行清
所以这也导致了永久代的区域会随着加载的 Class 的增多而胀满,最终抛出 OOM 异常
在 Java8 中,永久代已经被移除,被一个称为“元数据区”(元空间)的区域所取代
元空间的本质和永久代类似,元空间与永久代之间最大的区别在

GC回收机制的方法

  1. 标记-清理:通过可达性遍历堆内存,把'存活'对象与'垃圾'对象进行标记,把所有垃圾对象所占的空间清空,但容易产生内存碎片
  2. 标记-整理:在清理的时候,把所有的存活对象扎堆到同一个地方,让他们待在一起,就没有内存碎片了
  3. 复制:把堆内存分成两部分,一段时间内只允许在一块内存区进行分配,分配完成后,则执行垃圾回收

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值