主要是针对HotSpot虚拟机来说的

1.对象的创建过程-new 对象()

1.1检查类是否被加载

  检查创建的这个对象的类是否能在常量池中找到类的符号引用,并检查这个类是否被加载、解析和初始化。如果没有,先要进行类的加载

1.2在堆中分配内存

  对象需要分配的大小是在类加载完成后就可以确定的,需要做的就是在堆中分配出一块指定大小的内存区域

1.2.1分配的两种方法

1)指针碰撞

  如果堆的内存是规整的,那么内存就清晰的分为已用和空闲两部分,中间由指针隔开。分配内存时,只需要移动指针即可。

2)空闲列表

  如果堆的内存是不规整的,已使用的内存和空闲的内存交错在一起。虚拟机就会维护一个列表,记录那些内存时空闲的,在分配的时候找出一块足够大小的内存块分配出去。(如果要分配32b,现在最小的空闲的是64,是不是分配32b出去,剩余的32b还记录在在空闲列表里面),并且更新列表

3)两种分配方法的决定因素

  由堆内存是否规整决定,堆内存是否规整是由垃圾回收期是否拥有压缩整理的能力决定的。有则是规整的,没有是不规整的。

1.2.2分配内存中的线程安全问题

  即使仅仅移动个指针,都存在并发安全问题。正在给对象A分配内存,指针还没来得及修改,对象B使用了原来的指针,就出现了线程安全问题。

  虚拟机有两种解决方案

  1)CAS+自旋锁保证操作的原子性(https://www.cnblogs.com/jthr/p/14700940.html)

  2)使用本地线程分配换缓冲区TLAB,为每个线程预先分配一块内存区域,称为本地线程分配换缓冲区。线程需要为对象分配内存时,在自己的分配缓冲区进行分配即可。只有本地线程分配换缓冲区不够用时,需要分配新的缓冲区,这个时候才需要同步。虚拟机是否使用TLAB,可以通过设置参数-XX:+/-UseTLAB来设定

1.3堆对象的内存空间除了对象头外(也就是对实例数据)都初始化为零值

  这部工作保证对象实例字段在JAVA代码中可以不必赋初始值就可以使用。,使程序能够访问到这些字段所对应的类型的零值

1.4 对对象进行必要的设置

  这个对象是哪个类的实例、怎么能够找到类的元数据、对象的哈希码、对象的GC分代年龄等信息。这些信息都存放在对象头

1.5运行init方法

  执行代码块、构造方法。对对象进行初始化。

2.对象的内存布局

  对象头、实例数据、对齐填充

  对象头:对象头又包括两类:markword,class pointer,

https://www.cnblogs.com/jthr/p/15980849.html

2.1对象头

  对象头包含两类信息。

  第一类是用于存储对象自身的运行时数据,如哈希码、GC年龄分代、锁状态标志、线程持有的锁、偏向线程id、偏向时间戳等(这几个东西都是什么东西???)

  另外一类是类型指针。即对象指向它的类的元数据的指针。java虚拟机通过它来确定对象数据哪个类的实例,找到对象的元数据。如果对象是一个数组,那么对象头还必须有数组长度。因为虚拟机可以通过对象的元数据确定对象的大小,但是如果不知道数组长度,将无法通过对象元数据学习确定数组对象的大小

2.2实例数据

  这是对象真正存储的有效信息。即我们代码定义的各种字段的内容。

2.3对齐填充

  这部分不是必有的。它仅仅起占位符的作用。HotSpot要求对象的起始地址必须是8字节的整数倍。也就是说对象的大小必须是8字节的整数倍。对象头已经被设计为了8的整数倍,不会有对齐填充。但是,如果对象实例数据部分没有对齐的话,就通过对齐填充来补全

3对象的访问定位

  创建对象后使用对象,java通过reference类型指向对象的引用。reference通常使用两种方式,句柄和直接指针。

3.1句柄

  java对中会划分一块区域为句柄池,用于维护句柄。reference存的是句柄的地址。句柄中包含了对象实例数据的指针和对象类型数据的指针

3.2直接指针

  reference存的是对象地址。这里对象实例存放对象类型数据的指针

3.3优劣

  使用句柄的好处是reference存储的是稳定的句柄地址。对象移动是句柄的地址不会变化,只是句柄里面的指针需要修改。

  使用直接指针的好处是速度更快。对于HotSpot而言,它主要使用直接指针。

JAVA虚拟机04---对象的创建的更多相关文章

  1. JAVA虚拟机:对象的创建过程

    简要说明的话,Java对象的创建过程分为下面几步: 1.执行相关检查: 2.为对象分配内存,将分配到的内存空间都初始化为零值: 3.进行构造代码块和构造函数的初始化 下面详细介绍这几个步骤: 1.执行 ...

  2. Java虚拟机学习-对象的创建

    虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已经被加载.解析和初始化过.如果没有,必须先执行相应类的加载过程. 类加载 ...

  3. JAVA虚拟机:对象的创建

    在虚拟机中,当遇到需要new一个对象时,虚拟机首先会去处于方法区的常量池中查找new指令的参数,即查找此类的符号引用是否已存在,并且检查此符号引用的代表类是否已经做过加载.解析和初始化,如果做过则不会 ...

  4. 深入Java虚拟机--判断对象存活状态

    程序计数器,虚拟机栈和本地方法栈 首先我们先来看下垃圾回收中不会管理到的内存区域,在Java虚拟机的运行时数据区我们可以看到,程序计数器,虚拟机栈,本地方法栈这三个地方是比较特别的.这个三个部分的特点 ...

  5. JAVA虚拟机之对象探秘

    上一章主要写到了JVM中运行时数据区域各个部分的功能及其作用.上一章说到了对象是分配在堆上面的,所以接下来我们写到对象在堆内存中是如何创建.如何布局.如何访问.1. 对象的创建 在java程序中对象的 ...

  6. Java 虚拟机的对象创建

    堆中存储的内容:在程序运行时,动态创建的对象. 创建对象的四种方式:new,clone(浅复制),反射,反序列化. 浅复制:只能复制当前对象本身,如果当前对象(A)引用了另外的对象(B),则引用对象( ...

  7. Java虚拟机(二)-对象创建

    这一篇大致说明一下,对象在Java堆中对象分配.内存布局以及访问定位 1.对象的创建 虚拟机在遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引 ...

  8. 带着新人看java虚拟机04(多线程篇)

    我记得最开始接触多进程,多线程这一块的时候我不是怎么理解,为什么要有多线程啊?多线程到底是个什么鬼啊?我一个程序好好的就可以运行为什么要用到多线程啊?反正我是十分费解,即使过了很长时间我还是不是很懂, ...

  9. Java虚拟机学习 - 对象访问

    对象访问会涉及到Java栈.Java堆.方法区这三个内存区域. 如下面这句代码: Object objectRef = new Object(); 假设这句代码出现在方法体中,"Object ...

  10. Java虚拟机判定对象存活算法

    1.引用计数算法 描述:给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1:当引用失效时,计数器值就减1:任何时刻计数器值为0的对象就是不可能再被使用的. 特点:实现简单,判定效率高. ...

随机推荐

  1. 嵌入式-C语言基础:指针是存放变量的地址,那为什么要区分类型?

    指针是存放变量的地址,那为什么要区分类型?不能所有类型的变量都用一个类型吗?下面用一个例子来说明这个问题. #include<stdio.h> int main() { int a=0x1 ...

  2. 《回炉重造》——Lambda表达式

    前言 Lambda 表达式(Lambda Expression),相信大家对 Lambda 肯定是很熟悉的,毕竟我们数学上经常用到它,即 λ .不过,感觉数学中的 Lambda 和编程语言中的 Lam ...

  3. 6. PyQt5 中的多线程的使用(上)

    专栏地址 ʅ(‾◡◝)ʃ 这一节引入了多线程这个非常重要概念, 在我认为多线程的重要性是紧紧次于信号与槽函数的, 因为在平时经常使用 1. 为什么要用多线程 先看下面这一个示例代码 6.1 from ...

  4. day31-JQuery04

    JQuery04 6.jQuery的DOM操作02 6.9常用遍历节点方法 取得匹配元素的所有子元素组成的集合:children(),该方法只考虑子元素而不考虑任何后代元素 取得匹配元素后面的同辈元素 ...

  5. python 运算优先级

    python 运算优先级,请见下图

  6. ES6——模块化

    模块化 模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来. 一.浏览器使用ES6模块化方式一 使用script标签,将type属性设置为module,然后在script中书写代码 ...

  7. 网络工具netstat与ss

    建议使用ss命令,2001年的时候netstat 1.42版本之后就没更新了,之后取代的工具是ss.netstat命令在很多场景下比较慢.ss可以显示跟netstat类似的信息,但是速度却比netst ...

  8. CH9434-MCU代码移植,芯片使用详细说明(附Linux开发资料链接)

    简介 CH9434是一款SPI转四串口转接芯片,提供四组全双工的9线异步串口,用于单片机/嵌入式/安卓系统扩展异步串口.提供25路GPIO,以及支持RS485收发控制引脚TNOW.本篇基于STM32F ...

  9. CH334U与FE1.1S功能对比

    CH334U与FE1.1S功能对比 介绍: CH334U是符合 USB2.0 协议规范的高性能MTT 4 端口 USB2.0  HUB 控制器芯片,高ESD特性,工业级设计,外围精简,可应用于计算机和 ...

  10. 使用插件式开发称重仪表驱动,RS232串口对接各类地磅秤数据实现ERP管理

    在ERP系统中,采集一线的生产数据是重要工作之一,而称重计量是企业的核心资产数据,人工计重费时费力,还容易出错,重量数据是否正确,直接影响企业的采购或销售额.基于此,由系统对接电子秤实现自动抓取数据是 ...