以常用的HotSpot虚拟机和JAVA内存区域堆为例,探讨对象的创建,对象的内存布局以及对象的访问定位

一.对象的创建

1)类加载:虚拟机遇到一条new指令时,先检测这个指令的参数能否在常量池中定位到一个类的符号的引用,并检查这个符号代表的类否收以及被加载,解析和初始化,如果没有那么就必须执行相应的类加载过程

2)分配内存:如果java堆的内存是绝对规整的,那么采用指针碰撞的方式分配内存,即所有空闲的内存放一边,不空闲的内存放一边,中间放着一个指针作为分界点的指示器,分配内存就仅仅是把那个指针向空闲的空间那边挪动一段与对象大小相等的距离,如果java堆的内存是不规整的话,那么我们必须维护一个空闲列表,记录哪些内存块是可用的,在分配的时候从列表中找到一个足够大的空间划分给对象实例,并更新列表上的记录

3)初始化:都初始化为0(不包括对象头),这一步操作保证了对象的实例字段在java代码中可以不赋初始值就直接使用

4)对象头的设置:对象是那个类的实例,如何找到类的元数据,对象的哈希码,对象的GC分代年龄,以及是否启动偏向锁等

5)程序员按照自己的意愿进行对象初始化

思考:对象的创建在虚拟机中是频繁的行为,如何保证并发情况下的线程安全呢?

比如正在给对象A分配内存,指针还没有来得及修改,对象B又同时使用了原来的指针分配内存

解决方案:

1)对分配内存空间的动作进行同步:实际上虚拟机采用CAS配上失败重试的方式保证更新操作的原子性

2)把内存分配的动作按照线程的不同划分在不同的空间进行:每个线程在java堆中预先分配一块内存,称为本地线程分配缓存TLAB,那个线程需要分配内存,就在那个线程的TLAB上分配,只用TLAB分配完并分配先新的TLAB时,才需要同步锁定

二.对象的内存布局

在HotSpot虚拟机中,对象在内存区域中存储布局可以分为3个区域:对象头,实例数据,对齐补充

对象头:又分为Mark Word和类型指针,Mark Word存储哈希码,GC分代年龄,锁状态标志,线程持有的锁,偏向线程ID,偏向时间戳等

,类型指针即对象指向它的类元数据的指针,虚拟机通过这个指针确定这个对象是哪个类的实例

实例数据:对象真正储存的有效信息,也就是在程序代码中所定义的各种类型的字段内容,无论是从父类继承来的,还是在子类中定义的,都需要记录来

对齐补充:并不是必然存在的,因为HotSpot要求对象的起始地址必须是8字节的整数倍,也就是对象的大小必须是8字节的整数倍,而对象头部分正好是8字节的整数倍,所以当对象的实例数据部分没有对齐时,就需要通过对齐补充来补全

三.对象的访问定位

java程序通过栈上的reference数据来操作堆上的具体对象,由于reference类型在java虚拟机规范中只规定了一个指向对象的引用,并没有定义这个引用应该通过何种方式去定位从而访问堆中的对象元素的具体位置,所以对象的访问方式是取决于虚拟机实现的,目前主流的方式有使用句柄和直接指针两种

句柄方式:堆中划分一块内存作为句柄池,reference中储存的就是对象的句柄地址,而对象的句柄地址中包含了对象的实例数据与类型数据各自具体的地址信息

直接指针:reference中储存的就是对象地址,java堆对象的布局需要考虑如何放置访问类型数据的相关信息

优劣分析:

1.使用句柄的最大好处就是reference中储存的是稳定的句柄地址,在对象被移动(垃圾收集时对象移动是非常普遍的行为)时只会改变句柄中实例数据指针,而refrence本身不需要修改

2.直接指针访问最大好处就是速度更快,节省了一次指针定位的时间开销,由于对象的访问在java中非常频繁,积累下来也是一笔很大的时间开销

参考书籍:深入理解JAVA虚拟机 java高级特性与最佳实践 第二版

HotSpot虚拟机对象探秘(对象创建,对象内存布局,对象访问定位)的更多相关文章

  1. 浅谈Java虚拟机内存中的对象创建,内存布局,访问定位

    参考于 深入理解Java虚拟机 这里介绍HotSpot虚拟机(自带的虚拟机) 1.对象的创建 对于程序员来说,创建对象的方法: User user1 = new User(); User user2 ...

  2. Java对象的创建、内存布局和访问定位

    在Java运行时数据区中,我们知道了虚拟机内存的概况,本文介绍虚拟机内存中的数据的其它细节,如对象如何创建.如何布局以及如何访问. 基于实用的原则,这里以HotSpot虚拟机和常用的内存区域Java堆 ...

  3. 【深入理解JVM】:Java对象的创建、内存布局、访问定位

    对象的创建 一个简单的创建对象语句Clazz instance = new Clazz();包含的主要过程包括了类加载检查.对象分配内存.并发处理.内存空间初始化.对象设置.执行ini方法等. 主要流 ...

  4. java面试-对象的创建、内存布局、访问定位

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

  5. 深入理解Java虚拟机(二)、Java对象的创建,内存布局和访问定位

    对象的创建: Object obj = new Object(); 常量池中是否有Ljava.lang.Object

  6. 【JVM之内存与垃圾回收篇】对象实例化内存布局与访问定位

    对象实例化内存布局与访问定位 从各自具体的内存分配上来讲 new 的对象放在堆中 对象所属的类型信息是放在方法区的 方法当中的局部变量放在栈空间 这 new 的对象怎么把三块粘合到一起 就是这章的内容 ...

  7. JVM 专题十二:运行时数据区(七)对象的实例化内存布局与访问定位

    1. 对象的实例化 1.1 创建对象的方式 new 最常见的方式 变形1 : Xxx的静态方法 变形2 : XxBuilder/XxoxFactory的静态方法 Class的newInstance() ...

  8. JVM运行时数据区--纵向补充--对象的实例化内存布局与访问定位

    对象的实例化 创建对象的方式 1.new:最常见的方式(本质是构造器) 变形1 : Xxx的静态方法 变形2 : XxBuilder/XxoxFactory的静态方法 2.Class的newInsta ...

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

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

  10. Java对象在虚拟机中的创建、内存分布、访问定位以及死亡判定

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6535156.html  一:虚拟机中对象的创建 1:虚拟机遇到new指令时,在常量池检索是否有对应的符号引用, ...

随机推荐

  1. zTree 节点文字过多处理方法

    zTree setting.view.addDiyDom 方法可以实现自定义控件,指定节点显示内容.因此需要自己实现addDiyDom方法. 如果树节点不显示checkbox ,处理方法为: func ...

  2. Nginx 图片服务器

    文件服务器:后台如果是集群,每次请求都会到不同的服务器,所以每台服务器的图片文件等都要做同步处理,才能保证每次用户不管访问到哪台服务器都能获取一样的资源.这种做法开销会很大,专门使用 nginx 作为 ...

  3. 16.Odoo产品分析 (二) – 商业板块(9) – 网站生成器(1)

    查看Odoo产品分析系列--目录 安装"电子商务"模块时,该模块会自动安装,但网站生成器是电子商务的前提,因此,先分析该模块,在下面就是对电子商务模块的分析. 1. 编辑网站 安装 ...

  4. 巧用 即刻搜索事件 input propertychange 监听输入框字数

    实时监听输入框的字数,大于200时,不再输入. 即时搜索: propertychange(ie)和input事件(常用) input是标准的浏览器事件,一般应用于input元素,当input的valu ...

  5. JSP(一):初识JSP

    在Servlet中,我们多次用到了jsp页面,今天就来仔细聊聊JSP. 一.概念 JSP全名是Java Server Pages,可理解为Java服务端页面,是一种动态网页开发技术,其本质是一个简化的 ...

  6. 强大而灵活的字体图标替代库iconfont

       前言概述 在开发网页制作过程中通常需要一些网页小图标,前端需要PS切图,将单个小图标icon组合成CSS雪碧图过程中,需要一些时间和精力; 如果网页制作中需要的小图标icon有一套css框架库集 ...

  7. 16.Python网络爬虫之Scrapy框架(CrawlSpider)

    引入 提问:如果想要通过爬虫程序去爬取”糗百“全站数据新闻数据的话,有几种实现方法? 方法一:基于Scrapy框架中的Spider的递归爬取进行实现(Request模块递归回调parse方法). 方法 ...

  8. 【Linux基础】VI命令模式下大小写转换

    [开始位置] ---- 可以指定开始的位置,默认是光标的当前位置 gu ---- 把选择范围全部小写 gU ---- 把选择范围全部大写 [结束位置] ---- 可以跟着类似的w,6G,gg等定位到错 ...

  9. 关于陌生的依赖模块,如withStyles、react-apollo等

    有自己不认识的依赖,可参考的学习方式: 1.各大技术分享网站的文章(最快) 2.npm官网下的文档(最全)

  10. Gulp的简单使用

    我比较喜欢使用Gulp,因为简单好用! 今天的任务是:使用Gulp来压缩 jQuery源码,各输出一个压缩的和未压缩的版本 第一步:安装 cnpm install gulp --save-dev cn ...