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

JVM三JVM虚拟机

对象的创建流程与内存分配

在这里插入图片描述

对象内存分配方式

​ 内存分配的方法有两种:不同垃圾收集器不一样

  • 指针碰撞(Bump the Pointer)
  • 空闲列表(Free List)
分配方法说明收集器
指针碰撞(Bump thePointer)内存地址是连续的(新生代)Serial 和ParNew 收集器
空闲列表(Free List)内存地址不连续(老年代)CMS 收集器和Mark-Sweep 收集器

指针碰撞示意图

在这里插入图片描述

内存分配安全问题

在JVM中有两种解决办法:

  1. CAS 是乐观锁的一种实现方式。虚拟机采用 CAS 配上失败重试的方式保证更新操作的原子性。
  2. TLAB本地线程分配缓冲(Thread Local Allocation Buffer即TLAB):为每一个线程预先分配一块内存

JVM在第一次给线程中的对象分配内存时,首先使用CAS进行TLAB的分配。当对象大于TLAB中的剩余内存或TLAB的内存已用尽时,再采用上述的CAS进行内存分配。

对象内存分配流程

在这里插入图片描述

对象怎样才会进入老年代

进入老年代的条件:四种情况

  1. 存活年龄太大,默认超过15次【-XX:MaxTenuringThreshold】
  2. 动态年龄判断:MinorGC之后,发现Survivor区中的一批对象的总大小大于了这块Survivor区的50%,那么就会将此时大于等于这批对象年龄最大值的所有对象,直接进入老年代。
  3. 大对象直接进入老年代:前提是Serial和ParNew收集器
  4. MinorGC后,存活对象太多无法放入Survivor

空间担保机制:当新生代无法分配内存的时候,我们想把新生代的老对象转移到老年代,然后把新对象放入腾空的新生代。此种机制我们称之为内存担保。

  • MinorGC前,判断老年代可用内存是否小于新时代对象全部对象大小,如果小于则继续判断
  • 判断老年代可用内存大小是否小于之前每次MinorGC后进入老年代的对象平均大小
    • 如果是,则会进行一次FullGC,判断是否放得下,放不下OOM
    • 如果否,则会进行一些MinorGC:
      • MinorGC后,剩余存活对象小于Survivor区大小,直接进入Survivor区
      • MinorGC后,剩余存活对象大于Survivor区大小,但是小于老年代可用内存,直接进入
        老年代
      • MinorGC后,剩余存活对象大于Survivor区大小,也大于老年代可用内存,进行FullGC
      • FullGC之后,任然没有足够内存存放MinorGC的剩余对象,就会OOM

对象内存布局

在堆中,对象里面都有些啥?

  1. 对象头(Header):Java对象头占8byte。如果是数组则占12byte。因为JVM里数组size需要使用4byte存储。

    • 标记字段MarkWord:
      • 用于存储对象自身的运行时数据,它是synchronized实现轻量级锁和偏向锁的关键。
      • 默认存储:对象HashCode、GC分代年龄、锁状态等等信息。
      • 为了节省空间,也会随着锁标志位的变化,存储数据发生变化。
    • 类型指针KlassPoint:
      • 是对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例
      • 开启指针压缩存储空间4byte,不开启8byte。
      • JDK1.6+默认开启
    • 数组长度:如果对象是数组,则记录数组长度,占4个byte,如果对象不是数组则不存在。
    • 对齐填充:保证数组的大小永远是8byte的整数倍。
  2. 实例数据(Instance Data):生成对象的时候,对象的非静态成员变量也会存入堆空间

  3. 对齐填充(Padding):JVM内对象都采用8byte对齐,不够8byte的会自动补齐。

在这里插入图片描述
在这里插入图片描述

对象头的大小:
对象头信息是与对象自身定义的数据无关的额外存储成本。考虑到虚拟机的空间效率,Mark Word被设计成一个非固定的数据结构,以便在极小的空间内,尽量多的存储数据,它会根据对象的状态复用自己的存储空间,也就是说,Mark Word会随着程序的运行发生变化,变化状态如下(JDK1.8)。

在这里插入图片描述

基本数据类型和包装类的内存占用情况:
在这里插入图片描述

如何访问一个对象呢

有两种方式:

  1. 句柄:稳定,对象被移动只要修改句柄中的地址
  2. 直接指针:访问速度快,节省了一次指针定位的开销

在这里插入图片描述
在这里插入图片描述


http://www.kler.cn/a/473050.html

相关文章:

  • JS进阶--JS听到了不灭的回响
  • IvorySQL 升级指南:从 3.x 到 4.0 的平滑过渡
  • leetcode 5. 最长回文子串
  • 进程间通讯
  • 行业商机信息付费小程序系统开发方案
  • 我在广州学 Mysql 系列——有关数据表的插入、更新与删除相关练习
  • 战地雷达通信系统中无人机与特种车辆智能组网及雷达通信一体化研究报告
  • UE蓝图节点备忘录
  • C++ 泛型编程:动态数据类模版类内定义、类外实现
  • 嵌入式系统 (2.嵌入式硬件系统基础)
  • 文献阅读分享:ChatGPT在推荐系统中的偏见研究
  • 使用Qt实现json数据的格式检测并序列化输出 Qt5.4.0环境
  • 根据docker file 编译镜像
  • 入门嵌入式(六)——定时器
  • GPIO输入及两个应用案例
  • 『SQLite』解释执行(Explain)
  • benchANT 性能榜单技术解读 Part 1:写入吞吐
  • 金融租赁系统助力行业转型与升级的创新之路
  • 生成模型:变分自编码器-VAE
  • 产品经理-商业模式构建 - AxureMost
  • SparkStreaming集群调优
  • H2数据库在单元测试中的应用
  • 实时数仓:Apache Iceberg 的表管理与实时数仓架构设计
  • [读书日志]从零开始学习Chisel 第八篇:Scala的集合(敏捷硬件开发语言Chisel与数字系统设计)
  • MySQL error [Warning] InnoDB: Table mysql/innodb_index_stats has length
  • win32汇编环境,怎么进行乘法运算的