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语 ...
随机推荐
- unity射线检测
unity中射线检测时非常实用也经常实用的一种手段.下面讲解一下射线检测问题. 1)Ray 根据射线端点和射线的方向定义一条射线 Ray ray= new Ray(transform.position ...
- 前后端对称加密(AES)
后端实现(JAVA) package com.vcgeek.hephaestus.demo; import org.apache.commons.codec.binary.Base64; import ...
- Shiro笔记---授权
1.搭建shiro环境(*) idea2018.2.maven3.5.4.jdk1.8 项目结构: pom.xml: <?xml version="1.0" encoding ...
- 从零开始用刚买的阿里云实例搭建lnmp环境(非集成包)
一.安装前 1. 更新系统软件: yum update 2. 查看是否已安装wget: rpm -qa wget 否则安装: yum install wget 3. 查看是否已安装编译器: rpm - ...
- 一个九位数-python
有一个9位数由1~9的9个数字组成, 每个数字只能出现一次:其第一位能被1整除, 前两位能被2整除, 前三位能被3整除...依次类推,前9位能被9整除.所有的9位数中,只有一个数字满足这些条件,请你输 ...
- [考试反思]0828NOIP模拟测试32:沉底
,,190,180,170,170... 倒数第6,75. 啊...再这么下去要失去理想了... 开学翘课停课以来的第一场考试,就考成这鬼模样. 本来还可以凭借那几次高分苟在公共卷总分的第2,这一场直 ...
- NOIP模拟27
两个机房又和在一起考试 开场看了看T1,感觉挺水的,过. T2,这个式子有点奇怪,暂时没什么思路,过 T3,好像保留最后几位换个根处理一下就行了,过,先去打T1 于是T1大概打了0.5h,连暴力带正解 ...
- CSPS模拟 45 乔迁之喜
搬家了qwq 暑假在机房藏的吃的还没来得及吃qwq 有缘人会发现它的(其实并没有) 我居然也能和skyh并列了啊sto T1 安排打怪 不可能让左边的人越过右边人打的怪去打更靠右的怪吧? $O(n^2 ...
- go语言教程之浅谈数组和切片的异同
Hello ,各位小伙伴大家好,我是小栈君,上次分享我们讲到了Go语言关于项目工程结构的管理,本期的分享我们来讲解一下关于go语言的数组和切片的概念.用法和区别. 在go语言的程序开发过程中,我们避免 ...
- NuGet Package Explorer使用教程下载
1.下载NuGet Package Explorer http://www.pc0359.cn/downinfo/91514.html 2.双击NuGet Package Explorer出现启动界面 ...