JVM(2)--深入理解java对象创建始终
java对象探秘
java是一门面向对象的语言,我们无时无刻不在创建对象和使用对象,那么java虚拟机是如何创建对象的?又是如何访问对象的?java对象中究竟存储了什么运行时所必需的数据?在学习了java虚拟机数据的存储区域后,再来探究一下对象是如何产生的?
对象是如何创建的?
对于使用者来说,创建对象仅仅只是new一个对象而已。但对于虚拟机来说,却是一系列的过程。

1.检查对象所属类是否进行过类加载
虚拟机在遇到一条new指令时,首先去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载,解析和初始化过。如果没有,那必须先执行相应的类加载过程。其实就是该类的实例对象是不是之前创建过。
2.为对象分配内存
对象所分配的内存在类加载完之后就能完全确认,但是如何在堆上为对象分配内存呢?怎么分配合理呢?就内存分配的算法,java虚拟机里面有两种策略,一种是“指针碰撞”,一种是“空闲列表”,采用哪种策略取决于内存是否规整,而内存是否规整又取决于收集器。这两种算法分别适应于两种收集器--带Compact过程的收集器,基于Mark-sweep的收集器。
- 指针碰撞:假设java堆中的内存是绝对规整的,所有用过的内存放在一边,所有空闲的内存放在另一边。中间放着一个指针用作分界区的指示器。那么分配内存就仅仅是把那个指针先空闲区域移动一个与对象同样大小的距离
- 空闲列表:如果java堆中的内存并不是规整的,用过的内存与未使用的内存交错在一起,那么就无法使用指针移动的方法来分配内存了。虚拟机会维护一个空闲列表,记录那些内存块是可用的,那些是不可用的,在分配内存的时候从空闲列表找到一个足够大的内存区域用来存放对象实例,并更新空闲列表。
- 并发情况下内存分配策略:在多线程环境下,为了保证对象成功创建,一般会采用CAS配上失败重试的方法保证更行操作的原子性,也还用另外一种方法,就是把内存分配的操作按照线程划分在不同的空间中进行(使用本地线程分配缓冲,TLAB)。
内存分配完之后,虚拟机需要将分配到的内存空间都初始化为零值(除对象头)
3.设置对象头
设置对象头信息,例如对象哈希码,对象GC分代年龄,类的元数据等。在Java虚拟机上创建对象的过程就算完成了,但是从Java程序上看,还没有进行<init>初始化。
对象的内部构造是这样的?

如何访问对象?
- 使用句柄
描述:reference指针指向一个句柄池,句柄池内包含了示例数据对象指针,对象类数据指针。
优点:reference存储的是稳定的句柄地址,在对象被移动(内存回收时)只改变句柄中的实例数据对象,而reference不需要修改 - 使用直接指针
描述:reference指针直接指向对象实例数据,对象实例数据内包含对象类数据指针
优点:速度更快,节省一次指针定位的时间
缺点:java对象访问频繁,开销较大
现在的Sun HotSpot一般采用句柄访问对象的方法。
JVM(2)--深入理解java对象创建始终的更多相关文章
- 深入理解Java对象的创建过程:类的初始化与实例化
摘要: 在Java中,一个对象在可以被使用之前必须要被正确地初始化,这一点是Java规范规定的.在实例化一个对象时,JVM首先会检查相关类型是否已经加载并初始化,如果没有,则JVM立即进行加载并调用类 ...
- (转)深入理解Java对象的创建过程
参考来源:http://blog.csdn.net/justloveyou_/article/details/72466416 摘要: 在Java中,一个对象在可以被使用之前必须要被正确地初始化,这一 ...
- 深入理解Java对象
深入理解Java对象(理清关系) 1.对象的创建过程: 所有创建过程如下所示: new 类名 根据new的参数在常量池中定位一个类的符号引用. 如果没有找到这个符号引用,说明类还没有被加载,则进行类的 ...
- 深入学习Java对象创建的过程:类的初始化与实例化
在Java中,一个对象在可以被使用之前必须要被正确地初始化,这一点是Java规范规定的.在实例化一个对象时,JVM首先会检查相关类型是否已经加载并初始化,如果没有,则JVM立即进行加载并调用类构造器完 ...
- 深入理解java虚拟机(二)HotSpot Java对象创建,内存布局以及访问方式
内存中对象的创建.对象的结构以及访问方式. 一.对象的创建 在语言层面上,对象的创建只不过是一个new关键字而已,那么在虚拟机中又是一个怎样的过程呢? (一)判断类是否加载.虚拟机遇到一条new指令的 ...
- 理解Java对象序列化(二)
关于Java序列化的文章早已是汗牛充栋了,本文是对我个人过往学习,理解及应用Java序列化的一个总结.此文内容涉及Java序列化的基本原理,以及多种方法对序列化形式进行定制.在撰写本文时,既参考了Th ...
- 深入理解Java对象序列化
关于Java序列化的文章早已是汗牛充栋了,本文是对我个人过往学习,理解及应用Java序列化的一个总结.此文内容涉及Java序列化的基本原理,以及多种方法对序列化形式进行定制.在撰写本文时,既参考了Th ...
- Java对象创建过程补遗
一.static修饰的东东是属于这个类的,是所有的该类的实例共享的,因此它们的初始化先于实例对象的初始化. 二.Java中没有静态构造方法,但是有静态代码块.当类中同时存在静态代码块和静态成员变量声明 ...
- 读书笔记jvm探秘之二: 对象创建
对象是面向对象设计语言无法回避的东西,可见其重要性,JAVA的对象相较于C++来说,不算很复杂,但是我们看到一句话背后往往有很多东西值得探讨(NEW关键字). 对象如何被创建? 首先一句简单的NEW语 ...
随机推荐
- JavaScript随机生成布尔值
//方法一 var rand = Boolean(Math.round(Math.random())); conosole.log(rand) // 方法二: var arr = [true,fals ...
- Vue躬行记(5)——组件通信
组件之间除了保持独立之外,还需要相互通信,本章将介绍几种通信的方式. 一.直接访问 Vue提供了三个实例属性,可直接访问父组件.子组件和根实例,如下所列. (1)$parent:父组件. (2)$ro ...
- ArangoDB图数据库--总参
参考文章: ArangoDB原生多模型数据库(百科) ArangoDB官网 ArangoDB数据库入门 arangodb-vs-cassandra arangodb-vs-mongodb2 Arang ...
- 百度语音合成---前端vue项目
☞:官方文档 ☞:网页示例 具体步骤: 1.通过 socket.io 接收后端传过来的数据. 2.判断是否在播放声音. 如果没有则直接获取百度 token 播放声音 3.如果有,则存入数组.声音播放 ...
- 一个基于Net Core3.0的WPF框架Hello World实例
目录 一个基于Net Core3.0的WPF框架Hello World实例 1.创建WPF解决方案 1.1 创建Net Core版本的WPF工程 1.2 指定项目名称,路径,解决方案名称 2. 依赖库 ...
- 【IT教程-Oracle】尚观Oracle白金级入门教程
链接: https://pan.baidu.com/s/1GMncQN6mpgaH3hZQjGelaA 提取码: qu6j
- 微服务SpringCloud之GateWay服务化和过滤器
Spring Cloud Gateway 提供了一种默认转发的能力,只要将 Spring Cloud Gateway 注册到服务中心,Spring Cloud Gateway 默认就会代理服务中心的所 ...
- CSS汇总之CSS选择器
要使用css对HTML页面中的元素实现一对一,一对多或者多对一的控制,这就需要用到CSS选择器. 一.通配符选择器 语法:*{ } 说明:通配符选择器可以选择页面上所有的html标签(包括body,h ...
- ubuntu 12 install redis
ubuntu 12 install redis 今天开始写数据server部分,大家初步的方案是用redis+mysql 所以要安装,下面记录安装的基本过程,留做后续参考 unbuntu 12 已经支 ...
- 使用Typescript重构axios(九)——异常处理:基础版
0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...