JVM 四. 对象布局

2023-11-11

一. 对象实例化相关

  1. 有哪些方式可以创建一个对象
  1. new 方式创建一个对象,由new方式创建对象又延伸出 Builder建造者方式,Factory工厂方 等静态方法方式
  2. Class的newInstance(),反射方式,要求只能调用孔灿构造器,权限必须是public
  3. Constructor的newInstance(),基于反射方式,可以调用空参,带参,并且权限没要求,实用性更广
  4. clone()方式,当前类要实现Cloneable接口,实现clone(),注意默认是浅拷贝
  5. 反序列化方式, 基于文件,网络,读取二进制流然后反序列化
  6. 基于第三方库的Objenesis利用asm字节码技术动态生成Constructor对象

创建对象的步骤

创建对象的步骤简述:

  1. 首先判断对象是否被加载
  2. 为对象分配内存
  3. 处理并发安全问题
  4. 初始化分配到的空间
  5. 设置对象的对象头
  6. 执行init方法进行初始化
  1. 首先判断对象是否被加载: 虚拟机接收到new指令,先检查这个指令的参数能否在Metaspace的常量池中定位到当前需要new类的符号引用,也可以理解为检查常量池中是否有对应这个对象的类,既判断类元信息是否存在
  1. 如果没有,那么在双亲委派模式下使用当前类加载器以ClassLoader+包名+类名为key查找对应的.class文件
  2. 如果没找到对应的.class文件则抛出ClassNotFoundException异常
  3. 如果找到了则进行加载生成对应的Class类对象
  1. 为对象分配内存空间: 也就是计算对象占用空间的大小,在堆中开辟内存空间,如果实例成员变量是引用类型,仅分配引用变量空间,既4个字节,分配内存空间时有两个注意点:指针碰撞与空闲列表
  1. 指针碰撞: 如果内存规整使用指针碰撞,意思就是当所有用过的内存与未使用的内存时规整区分开的,通过中间的一个指针作为分界点的指示器,分配内存就是把指针想空闲那边挪动一段与对象大小相等的距离,如果垃圾收集器使用压缩算法(也就是没有垃圾碎片时),虚拟机采用这种分配方式
  2. 空闲列表: 如果内存不规整有碎片时,虚拟机要维护一个列表,使用这个空闲列表进行分配, 也就是当有内存碎片时以使用的内存与未使用的内存相互交错,虚拟机通过一个列表记录哪些内存块时可用的,分配时从列表中找到一款足够大的空间分配给对象实例,然后更新列表,CMS采用这种算法
  1. 处理并发安全问题: 创建对象是非常频繁的,虚拟机需要保证并发问题,采用了CAS, TLAB两种方式(也就是多个线程同时操作堆空间,防止出现并发问题,例如两个线程同时修改堆内存中同一个位置的数据,通过CAS或TLAB来保证安全问题,一个是基于cas重试,一个是不同线程操作不同位置)
  1. CAS: 通过失败重试, 区域加锁, 保证指针更新操作的原子性
  2. TLAB: 把内存分配的动作按照线程划分在不同的空间进行,既美观线程在java堆中预先分配一小块内存,称为本地线程分配缓冲区,虚拟机是否使用TLAB,可以通过"-XX:+/-UseTLAB"来设置
  1. 初始化分配到的空间: 在内存分配结束后,虚拟机将分配到的内存空间都初始化为0(不包括对象头),保证对象的实例字段在java代码中可以不用付初始化值可以直接使用,程序能方位到这些字段的数据类型对应的零值,也就是对对象布局中指的实例数据进行初始化
  2. 设置对象的对象头: 对对象头中GC信息,锁信息,HashCode,对齐填充等信息进行初始化设置
  3. 执行init方法进行初始化: 初始化成员变量,执行实例化代码块静态成员初始化, 调用类的构造方法,并把堆内对象的首地址值赋值给引用变量,

二. 对象的内存布局

  1. 对象头,实例数据, 对齐填充 具体查看"JUC 对象布局"笔记

三. 对象的访问定位

  1. 上面我们将了创建对象,而创建对象的目的就是为了获取对象,使用它,
  2. 对象访问方式有虚拟机实现而定,有两种方式: 使用句柄访问, 直接使用指针访问
  3. 直接使用指针访问: 引用中存储的就是对象的地址,通过这个地址获取到堆中对象实例
    在这里插入图片描述
  4. 使用句柄访问: 使用句柄访问时堆中会划分出一块内存被称为句柄池,栈中引用存放的对象的句柄池地址,句柄池中存放着对象实例与类型数据各地址信息,然后再通过这两个地址值获取到对象实例与类型, 使用句柄池的好处: 当对象被移动时例如垃圾回收移动对象,只需要改变句柄中实例数据指针即可,引用中的地址值不需要修改
    在这里插入图片描述
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JVM 四. 对象布局 的相关文章

随机推荐

  • Flutter沉浸式透明状态栏-flutter自定义凸起BottomAppBar导航

    注意 flutter项目默认是使用Kotlin语言 在Google I O 2017中 Google 宣布 Kotlin 取代 Java 成为 Android 官方开发语言 Kotlin详情见 https www kotlincn net
  • 异常处理--java.lang.reflect.MalformedParameterizedTypeException

    异常信息 org springframework beans factory BeanCreationException Error creating bean with name sqlSessionFactory defined in
  • C语言指针详解

    1 指针是什么 指针是内存中一个最小单元的编号 也就是地址 平时口语中说的指针 通常指的是指针变量 是用来存放内存地址的变量 所以 指针就是地址 口语中说的指针通常指的是指针变量 1 指针变量 我们可以通过 取地址操作符 取出变量的内存其实
  • 活动效果评估体系,该怎么搭建?

    如果让你来评估这次活动 你会怎么分析 无论是面试还是工作 做数据分写的同学都经常遇到这个问题 今天我们系统讲解一下 场景还原 某音乐类APP 对新用户进行一个新注册即送7天会员权益的活动 用户注册后 自主决定是否点击领取 为期1个月 问 如
  • python函数定义参数类型和返回值类型

    python中我们也可以定义函数的参数类型和返回值类型 如下代码 函数参数和返回值的类型声明 python函数类型的声明 更加有意义 更加实用一些 def add a b param a int param b int return int
  • C++ STL中map.erase(it++)用法原理解析

    之前在代码中使用map erase函数时 误搬了vector erase的用法 导致Server down掉了 好在在测试环境就及时发现了问题 在上线前进行了补救 以下总结一下map erase的正确用法 首先看一下在循环中使用vector
  • 灰灰-325-326-327-2019中南大学计算机上机-走台阶(3)

    1 n个台阶 一次走1阶或2阶 问走n阶有多少可能 1 lt n lt 1000 000 结果用1000 0000 7取模输出 输入格式 输入台阶数n 输出格式 结果用1000 0000 7取模输出 输入样例 3 输出样例 3 includ
  • 【技巧】各编辑器基础开发快捷键

    文章目录 一 IDEA 二 vim 1 各个模式的相互切换 2 正常模式 3 插入模式 4 底行模式 5 视图模式 三 Visual Studio 2017 四 PyCharm 一 IDEA psvm 回车 快速打出main函数 sout
  • docker网络自定义

    docker网络自定义 书接上回 我们认识了docker0网络以及 link参数的使用 https blog csdn net hello list article details 124815842 今天来了解下docker自定义网络 那
  • Java描述贪心算法解决背包问题

    思路 首先将物品根据性价比排好序在一个集合里 性价比 价格 重量 然后根据性价比从大到小依次依次放入背包 如果没办法放入这个物品的全部 就放入一部分 如果可以放入全量物品 就放入全量物品 Main java的代码 import java u
  • get和post区别

    get参数通过url传递 post放在post是放在请求头的包体 request body 中 因为参数直接暴露在url中 get比post更不安全 所以不能用来传递敏感信息 get请求在url中传递的参数是有长度限制的 get提交的数据最
  • 『动态规划·差分』队列

    P r o b l e m mathrm Problem Problem S o l u t i o n mathrm Solution Solution 首先考虑第一小问 问题转化为 每一行的问题互相独立 令 c j a i j a 1
  • Java之经典排序算法(一)

    一 冒泡排序 不稳定的排序算法 快希选堆 1 算法思路 比较相邻元素 如果第一个比第二个大 则交换这两个元素 从第一个元素开始依次往后比较相邻两个元素 直到最后一个比较完 这样最后一个元素就是最大的元素 再次从第一个元素开始依次往后比较相邻
  • 锁,避免虚假唤醒,注意死锁

    unique lock
  • 记录kitti数据集的坐标系转换问题

    Calib文件说明 以00000 txt文件为例 详细介绍每行含义 P0 7 070493000000e 02 0 000000000000e 00 6 040814000000e 02 0 000000000000e 00 0 00000
  • DC-DC电源模块输出先放大电容还是小电容

    最好的资料是电容厂家的设计指南 1 电容简单的等效模型是C ESL ESR 2 通常电解电容容量越大 ESR越小 ESL越大 承受纹波电流越大 3 电流流经阻抗最小路径 4 大电流 PCB走线电阻不能忽略 高频纹波电流PCB走线电感不能忽略
  • C语言之结构体内存的计算

    结构体的内存 一 提出疑问 结构体占用的是一片连续的内存空间 大小是由成员变量的类型决定的 但并不是计算所有成员变量的类型大小之和那么简单 先举一个实例 struct student int age 4个字节 int telephone 4
  • win系统使用frp端口映射实现内网穿透,配置“任务计划程序”提高稳定性

    Github下载最新版frp https github com fatedier frp releases download v0 48 0 frp 0 48 0 windows amd64 zip 解压把frpc exe和frpc ini
  • 【2】Python爬虫:分析AJAX传递的JSON获取数据-初步分析动态网页(1)

    前言 这是本人写的第二篇文章 希望能够帮助到一些和我一样的python爬虫初学者 在第一篇文章中 我总结了最近学到的利用requests和bs4第三方库共同作用 基本可以应对python获取静态网页数据的相关问题 但是如果现实中的网页往往比
  • JVM 四. 对象布局

    目录 一 对象实例化相关 创建对象的步骤 二 对象的内存布局 三 对象的访问定位 一 对象实例化相关 有哪些方式可以创建一个对象 new 方式创建一个对象 由new方式创建对象又延伸出 Builder建造者方式 Factory工厂方 等静态