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. ArcGIS Engine制作DIY地图工具

    本节将向你介绍,利用ToolStrip制作自定义GIS工具条. 步骤如下: ①向ToolStrip中添加一个Button ②向该Button的lmg属性添加图片素材,并将Button的图片比例(Ima ...

  2. vue学习笔记(一)入门

    前言 随着前端不断的壮大,许多公司对于前端开发者的需求也越来越多了,作为一名优秀的前端工程师,如果连vue和react都不会的话,那真是out了,为什么那么说呢?这是我在招聘网站上截的一张图,十家公司 ...

  3. 前端技术之:如何运行使用了ES(import)的node程序

    方式一: 在package.json文件的scripts域中,配置以下的命令:   "start": "cross-env NODE_ENV=dev node -r es ...

  4. 智学网电脑端查分小工具 已更新V2.2

    特别鸣谢这段代码的源作者,我的大佬同学\(MetalkgLZH\).由于我没有做什么工作,这篇随笔基本不含相关技术细节. 再次强调,这个程序的主要部分由\(MetalkgLZH\)完成.技术细节与源码 ...

  5. SpringBoot系列:Spring Boot定时任务Spring Schedule

    Spring Schedule是Spring提供的定时任务框架,相较于Quartz,Schedule更加简单易用,在中小型应用中,对于大部分需求,Schedule都可以胜任. 一.Spring Sch ...

  6. bzoj1004 card

    明知是burnside然而根本不会然后无耻地颓了题解后一脸傻气的我: 直接套公式???为啥方案数==等价类数量啊??? skyh:显然啊(狂笑)(hey wxy!他问为啥方案书等于等价类数量!) wx ...

  7. AndroidOS体系结构

    首先上图一张 对照着图,我们再来看Android 系统的体系结构就爽多了.我们从底层向上进行分析. 一.Linux 内核层 Linux Kernel 基于linux2.6.其核心系统服务如安全性.内存 ...

  8. vue+element UI + axios封装文件上传及进度条组件

    1.前言 之前在做项目的时候,需要实现一个文件上传组件并且需要有文件上传进度条,现将之前的实现过程简单记录一下,希望可以帮助到有需要的人. 项目用的是Vue框架,UI库使用的是element UI,前 ...

  9. tslib1.1移植

    安装步骤: 1.准备工作确保以下软件已安装 # apt-get install autoconf(或autoconf2.13)# apt-get install automake# apt-get i ...

  10. show语句大全

    基于本人对MySQL的使用,现将常用的MySQL show 语句列举如下: 1.show databases ; // 显示mysql中所有数据库的名称 2.show tables [from dat ...