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

创建流程

对象创建的流程图如下:

对象的内存分配方式

内存分配的方式有两种:

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

指针碰撞

指针碰撞示意图如下:

内存分配安全问题:

虚拟机给A线程分配内存的过程中,指针未修改,此时B线程同时使用了该内存,就会出现问题。

解决方式:

  • CAS乐观锁:JVM虚拟机采用CAS失败重试的方式保证更新操作的原子性;
  • TLAB (Thread Local Allocation Buffer)本地线程分配缓存,预分配。

分配主流程

首先从TLAB里面分配,如果分配不到,再使用CAS从堆里面划分。

对象如何进入老年代

对象进入老年代流程如下:

  • 新对象大多数默认都进入Eden;

  • 对象进入老年代的四种情况:

    • 年龄太大 MinorGC15次-XX:MaxTenuringThreshold】;

    • 动态年龄判断:MinorGC后会动态判断年龄,将符合要求对象移入老年代;

      MinorGC之后,发现Survivor区中的一批对象的总大小大于了这块Survivor区的50%,那么就会将此时大于等于这批对象年龄最大值的所有对象,直接进入老年代。

      例子: Survivor区中有一批对象,年龄分别为年龄1+年龄2+年龄n的多个对象,对象总和大小超过了Survivor区域的50%,此时就会把年龄n及以上的对象都放入老年代。希望那些可能是长期存活的对象,尽早进入老年代。
      比率可以由-XX:TargetsurvivorRatio指定
    • 大对象直接进入老年代1M【-XX:PretenureSizeThreshold 】;(前提是Serial和ParNew收集器)

      为了避免大对象分配内存时的复制操作降低效率。

      避免了Eden和Survivor区的复制。

    • MinorGC后存活对象太多无法放入Survivor。

空间担保机制

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

空间担保流程图如下:

对象内存布局

对象内存布局示意图如下:

对象里的三个区

堆内存中,一个对象在内存中存储的布局可以分为三块区域:

堆内存中,一个对象在内存中存储的布局可以分为三块区域:

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

    • 标记字段MarkWord:

      • 用于存储对象自身的运行时数据,它是synchronized实现轻量级锁和偏向锁的关键。

      • 默认存储:对象HashCode、GC分代年龄、锁状态等等信息。

      • 为了节省空间,也会随着锁标志位的变化,存储数据发生变化。

    • 类型指针KlassPoint:

      • 是对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例
      • 开启指针压缩存储空间4byte,不开启8byte。
      • JDK1.6+默认开启
    • 数组长度:如果对象是数组,则记录数组长度,占4个byte,如果对象不是数组则不存在。

    • 对齐填充:保证数组的大小永远是8byte的整数倍。

  • 实例数据(Instance Data):生成对象的时候,对象的非静态成员变量也会存入堆空间

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

如何访问一个对象

有两种方式:

  1. 句柄:稳定,对象被移动只要修改句柄中的地址

  2. 直接指针:访问速度快,节省了一次指针定位的开销

JVM—对象的创建流程与内存分配的更多相关文章

  1. Java中对象创建时的内存分配

    一.前言知识铺垫   1.逃逸对象:在一个方法内创建的对象没有被外界引用则称该对象为未逃逸的对象. 2.JDK1.6以后的HotSpot虚拟机支持运行时的对象逃逸分析. 3.JVM中的参数配置: 1) ...

  2. spring中容器和对象的创建流程

    容器和对象的创建流程 1.先创建容器 2.加载配置文件,封装成BeanDefinition 3.调用执行BeanFactoryPostProcessor 准备工作: 准备BeanPostProcess ...

  3. jvm系列 (二) ---垃圾收集器与内存分配策略

    垃圾收集器与内存分配策略 前言:本文基于<深入java虚拟机>再加上个人的理解以及其他相关资料,对内容进行整理浓缩总结.本文中的图来自网络,感谢图的作者.如果有不正确的地方,欢迎指出. 目 ...

  4. 【JVM.2】垃圾收集器与内存分配策略

    垃圾收集器需要完成的3件事情: 哪些内存需要回收? 什么时候回收? 如何回收? 在前一节中介绍了java内存运行时区域的各个部分,其中程序计数器.虚拟机栈.本地方法栈3个区域随线程而生,随线程而灭:栈 ...

  5. 【Java杂货铺】JVM#Java高墙之GC与内存分配策略

    Java与C++之间有一堵由内存动态分配和垃圾回收技术所围成的"高墙",墙外的人想进去,墙外的人想出来.--<深入理解Java虚拟机> 前言 上一章看了高墙的一半,接下 ...

  6. TObject简要说明-对象的创建流程

    TObject = class    //创建    constructor Create;    //释放    procedure Free;    //初始化实列    class functi ...

  7. JVM优化之垃圾收集器以及内存分配

    在jvm中,实现了多种垃圾收集器,包括:串行垃圾收集器.并行垃圾收集器.CMS(并发)垃圾收集器.G1垃圾收集器,接下来,我们一个个的了解学习. 串行垃圾收集器 串行垃圾收集器,是指使用单线程进行垃圾 ...

  8. JVM学习十 -(复习)内存分配与回收策略

    内存分配与回收策略 对象的内存分配,就是在堆上分配(也可能经过 JIT 编译后被拆散为标量类型并间接在栈上分配),对象主要分配在新生代的 Eden 区上,少数情况下可能直接分配在老年代,分配规则不固定 ...

  9. JVM读书笔记之垃圾收集与内存分配

    1 概述 说起垃圾收集( Garbage Collection , GC ) ,大部分人都把这项技术当做 Java 语言的伴生产物.事实上, GC 的历史远远比 Java 久远,1960 年诞生于 M ...

  10. Java对象(创建过程、内存布局、访问方法)

    (Java 普通对象.不包括数组.Class 对象等.) ​ 对象创建过程 类加载 遇到 new 指令时,获取对应的符号引用,并检查该符号引用代表的类是否已被初始化.如果没有就进行类加载. 分配内存 ...

随机推荐

  1. django学习第十五天-modelform的补充

    基于form组件和modelform组件改造图书管理系统 详情可以去图书管理系统分类中查看 基于form组件和modelform组件改造图书管理系统 modelform的补充 class BookMo ...

  2. CGI, FastCGI, WSGI, uWSGI, uwsgi一文搞懂

    中间件 1.服务器中间件:nginx,apache 2.数据库中间件:介于应用程序和数据库之前的,MyCat 3.消息队列中间件:kafka,rabbitmq,Rocketmq CGI 1.CGI是一 ...

  3. 2021 虎符杯hate num 注入题

    前言 今天遇到个有意思的SQL盲注,花了不少功夫,也学到了新姿势,遂记录下来以备后续碰到相同场景使用. 题目 这是2021 虎符杯的一道web题,有一个目标站点且附带了源码. 源码内容包括: 主要逻辑 ...

  4. ABP模块签入GitLab后自动打包并推送到ProGet

    # 1.添加一个名为下划线的解决方案文件夹 # 2.把解决方案根目录下的几个必要的文件添加到上述文件夹下 # 3.修改NuGet.Config,添加私有NuGet服务器的网址,并配置用户名和密码: A ...

  5. go grpc流式和非流式的例子

    参考grpc官方:  https://grpc.io/docs/quickstart/go.html 或官方中文翻译: http://doc.oschina.net/grpc?t=60133 安装pr ...

  6. [杂项] 抢单可能需要的API

    淘宝时间戳 http://api.m.taobao.com/rest/api3.do?api=mtop.common.getTimestamp 京东库存查询 http://c0.3.cn/stock? ...

  7. C#---串口调试助手

    1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 usin ...

  8. React函数式组件使用@emotion时一定要注意的问题!

    怎么说呢,一个坑,踩了两天,总觉得是useSate和input的传值方法问题 在useMemo和useCallback反复测试问题 最后没办法,通过最傻方式,一点点注释代码,发现了问题 const C ...

  9. Ubuntu 与Windows 之间搭建共享文件夹

    工作中经常需要搭建Linux环境用于测试以及其他开发需求,办公电脑通常是Windows 系统,为便于让文件在两个系统之间传输,可以采取共享文件的方式实现: 1.安装samba 服务: sudo apt ...

  10. 【LLM】大模型落地-从理论到实践

    简述 按个人偏好和目标总结了学习目标和路径(可按需学习),后续将陆续整理出相应学习资料和资源. 学习目标 熟悉主流LLM(Llama, ChatGLM, Qwen)的技术架构和技术细节:有实际应用RA ...