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对象创建始终的更多相关文章

  1. 深入理解Java对象的创建过程:类的初始化与实例化

    摘要: 在Java中,一个对象在可以被使用之前必须要被正确地初始化,这一点是Java规范规定的.在实例化一个对象时,JVM首先会检查相关类型是否已经加载并初始化,如果没有,则JVM立即进行加载并调用类 ...

  2. (转)深入理解Java对象的创建过程

    参考来源:http://blog.csdn.net/justloveyou_/article/details/72466416 摘要: 在Java中,一个对象在可以被使用之前必须要被正确地初始化,这一 ...

  3. 深入理解Java对象

    深入理解Java对象(理清关系) 1.对象的创建过程: 所有创建过程如下所示: new 类名 根据new的参数在常量池中定位一个类的符号引用. 如果没有找到这个符号引用,说明类还没有被加载,则进行类的 ...

  4. 深入学习Java对象创建的过程:类的初始化与实例化

    在Java中,一个对象在可以被使用之前必须要被正确地初始化,这一点是Java规范规定的.在实例化一个对象时,JVM首先会检查相关类型是否已经加载并初始化,如果没有,则JVM立即进行加载并调用类构造器完 ...

  5. 深入理解java虚拟机(二)HotSpot Java对象创建,内存布局以及访问方式

    内存中对象的创建.对象的结构以及访问方式. 一.对象的创建 在语言层面上,对象的创建只不过是一个new关键字而已,那么在虚拟机中又是一个怎样的过程呢? (一)判断类是否加载.虚拟机遇到一条new指令的 ...

  6. 理解Java对象序列化(二)

    关于Java序列化的文章早已是汗牛充栋了,本文是对我个人过往学习,理解及应用Java序列化的一个总结.此文内容涉及Java序列化的基本原理,以及多种方法对序列化形式进行定制.在撰写本文时,既参考了Th ...

  7. 深入理解Java对象序列化

    关于Java序列化的文章早已是汗牛充栋了,本文是对我个人过往学习,理解及应用Java序列化的一个总结.此文内容涉及Java序列化的基本原理,以及多种方法对序列化形式进行定制.在撰写本文时,既参考了Th ...

  8. Java对象创建过程补遗

    一.static修饰的东东是属于这个类的,是所有的该类的实例共享的,因此它们的初始化先于实例对象的初始化. 二.Java中没有静态构造方法,但是有静态代码块.当类中同时存在静态代码块和静态成员变量声明 ...

  9. 读书笔记jvm探秘之二: 对象创建

    对象是面向对象设计语言无法回避的东西,可见其重要性,JAVA的对象相较于C++来说,不算很复杂,但是我们看到一句话背后往往有很多东西值得探讨(NEW关键字). 对象如何被创建? 首先一句简单的NEW语 ...

随机推荐

  1. fenby C语言 P25

    二维数组 #include <stdio.h> int main(){ int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}}; int sum=0, ...

  2. js自增图片切换

    使用js自增进行图片的切换 <!DOCTYPE html> <html lang="zh"> <head> <meta charset=& ...

  3. 2018.8.6 Python中的文件操作

    前言: 使用python来读写文件是非常简单的操作,我们使用open()函数来打开一个文件,获取到文件句柄.然后通过文件句柄就可以进行各种操作了,根据打开方式的不同能够执行的操作也会有相应的差异. 打 ...

  4. github实用的搜索小技巧

    查资源,学习优秀的框架,搜索是一种能力! 作为程序猿开发中最大的同性交友网站,github当之无愧,里面有很多优秀的开源框架,各种技术大佬混迹其中,有他们总结的学习教程,造好的轮子(开发的各种工具,技 ...

  5. Map文件从IDA到OD

    目录 什么是map文件 IDA与OD导出使用map文件 注意事项 使用OD载入导出的map文件 什么是map文件 什么是 MAP 文件? 简单地讲, MAP 文件是程序的全局符号.源文件和代码行号信息 ...

  6. crontab中部署Python脚本注意事项

    有时候手工执行Python脚本跑的好好的,但是部署到Linux的crontab中后,就会遇到一些问题,最近终于有空整理一下这方面的内容,其实也是自己也踩了一些别人踩过的坑!这里仅仅列举个人遇到的一些小 ...

  7. Feeling after reading《Jane Eyre》

    Yesterday I read and listened over the book named <Jane Eyre>, the book is very thoughtful, th ...

  8. 有关logistic(sigmoid)函数回归

    在神经网络中,经常用到sigmoid函数,y = 1 / (1+e-x) 作为下一级神经元的激活函数,x也就是WX(下文,W以θ符号代替)矩阵计算结果. 这个函数通常用在进行分类,通常分为1或0的逻辑 ...

  9. CSPS模拟 44

    状态不是很好吧 这套和前边是一套的, skyh在我旁边AK,好像开了三个对拍又在拼小人 T3 正解没调出来,暴力又忘交了qwq 当时心情都要爆炸了 T1 区间$gcd$乘区间长度的最大值 暴力是$n^ ...

  10. 深入了解 Java Resource && Spring Resource

    在Java中,为了从相对路径读取文件,经常会使用的方法便是: xxx.class.getResource(); xxx.class.getClassLoader().getResource(); 在S ...