当前位置: 首页 > news >正文

对象分配策略

对象创建后,究竟何去何从,对象在堆中又会经历哪些过程,本篇就会详细解释对象创建后直到对象被回收的整个过程。之前博主已经写过Minor GC、Major GC、Full GC的区别,而本篇也主要根据这几个GC开展。

对象回收过程流程如下图所示:
在这里插入图片描述
正常的对象生存过程:

首先进入新生代的Eden区,此后要么是朝生夕死的对象,在某次Minor GC中被回收,要么在新生代中熬过15次Minor GC(默认晋级老年代的分代年龄阈值为15),当对象进入老年代后,就很难轻易被回收了。当然,总有对象死亡的一天,只是时间问题罢了。

但在我们编码过程中,肯定不是所有的对象都会一直生存到最后,也会有一些特殊情况,而虚拟机也考虑到各种情况,也对其做出了应对。

详解上方流程图:

  • 在对象创建后首先会在Eden区分配,如果Eden区内可用内存足够分配该对象,就直接将对象在Eden去分配内存,如果Eden区内存不足够,就会触发Minor GC。在此次GC后,如果新生代空间足够,就继续分配对象到Eden。
  • 如果新生代空间依旧不够的话,就可以确定该对象是个大对象了,会直接放入老年代。当然,也没有十足的把握能直接放入老年代,当老年代最大可用连续空间依旧小于该对象所需空间时,就会触发Full GC。之后空间足够就分配给内存,不够就抛出OOM。

总体的流程就是这样,但细心的人会发现,文字所描述的过程跟图上有所差别,这里就不得不提一下JVM的动态对象年龄判定,和空间分配担保了。

  • 动态对象年龄判定: 为了能更好的适应不同程序的内存状况,HotSpot虚拟机并不是永远要求对象的年龄必须达到阈值才能进入老年代,如果在Survivor空间中相同年龄所有对象大小的总和大于Survivor空间的一半,那么年龄大于等于该年龄的对象就会直接进入老年代,无需等到 -XX:MaxTenuringThreshold中要求的年龄。
  • 空间分配担保:在发生Minor GC之前,虚拟机必须先检查老年代最大可用的连续空间是否大于新生代所有对象的总空间,如果此条件成立,那这一次的Minor GC可以确定是安全的。如果不成立,虚拟机会查看 -XX:HandlePromotionFailure参数的设置是否允许担保失败。如果允许,会继续检查老年代最大可用的连续空间是否大于历史晋升老年代对象的平均大小,如果大于,将尝试一次Minor GC,当然,这次Minor GC肯定是有风险的;如果小于,或者参数设置不允许担保,那么这一次就要改为Full GC。

相信大家结合动态对象年龄判定和空间分配担保机制,再去看这个流程图的时候,很多地方都豁然开朗。

http://www.lryc.cn/news/20812.html

相关文章:

  • 你可能不知道的前端监控方案
  • java spring AOP 完全注解开发
  • ctf pwn基础-4
  • bool与引用类型
  • tkinter界面的TCP通信/tkinter开启线程接收TCP
  • [SQL Statements] 基本的SQL知识 之DDL针对数据库的基本操作
  • Qt的MOC机制
  • Linux驱动——设备模型
  • .NET基础加强第一课--面向对象(OO)
  • 从Linux源码角度看套接字的Listen及连接队列
  • cesium: 显示闪烁的点(004)
  • 常见代码审计工具,代码审计为什么不能只用工具?
  • es8集群模式部署
  • OAuth2
  • 一、简单排序
  • 慢SQL出现原因、优化、开启慢查询日志
  • 要理解网络,其实不就是理解这三张表吗
  • Java异常架构与异常关键字
  • 【阅读笔记】SecureML: A System for ScalablePrivacy-Preserving Machine Learning
  • 【2023美赛】C题Wordle预测27页中文论文及Python代码详解
  • 【C++修行之路】STL——模拟实现string类
  • CorelDRAW2023最新版序列号使用教程
  • 【一天一门编程语言】Python 语言程序设计极简教程
  • 14、KL散度
  • TypeError: load() missing 1 required positional argument: ‘Loader‘解决方案
  • 【设计模式】 观察者模式介绍及C代码实现
  • 01-Maven基础-简介安装、基本使用(命令)、IDEA配置、(写jar,刷新自动下载)、依赖管理
  • 一、前端稳定性规约该如何制定
  • Docker(三)Docker网络
  • Js高级API