《深入理解java虚拟机》笔记(2)HotSpot虚拟机对象探秘
一、对象的创建
1、类加载: 虚拟机在遇到一条new指令时候,检查类是否已被加载、解析、初始化过,如果没有,则执行类加载过程。
2、分配内存:类加载完成后,则为新对象从java堆上分配内存,分配内存有两种方式:指针碰撞和空闲列表
- 指针碰撞
Java堆中内存是绝对完整的,用过和空闲的内存分别放在一边,中间用一个指针作为分界点的指示器。分配内存时就是将指针向空闲内存区域挪动一段与对象同样大小的距离。
- 空闲列表
Java对中内存不是规整的,用过的和空闲的内存相互交错,这种情况,虚拟机就必须维护一个列表,记录哪些内存是可用的。分配时候,从列表中找到一块足够大的内存划分给对象。
选用哪种分配方式由Java堆是否规整决定,是否规整又由垃圾收集器是否带有压缩整理功能决定。
3、分配内存时,在并发情况下也并不是线程安全的,可能出现正在给A分配内存,指针还没来得及修改,对象B又同时使用原来的指针来分配内存情况。
两种解决方案:
- 对分配动作做同步处理,采用CAS和失败重试的方式保证更新操作的原子性
- 把分配动作按照线程划分在不同的空间中进行,即每个线程在Java堆中预先分配一小块内存,称为本地线程分配缓冲(TLAB)。虚拟机是否使用TLAB,可通过-XX:+/-UseTLAB参数设定。
4、必要设置:内存分配完成后,会把内存空间都初始化为零值,同时虚拟机会对对象做一些必要的设置
如:这个对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希值、对象的GC分代年龄等信息。这些信息存放在对象头(Object Header)中。
5、init方法执行:完成以上流程,虚拟机已经完成了一个对象的创建,但从Java程序来看,对象创建才刚开始,所有字段都还为零。
所以紧接着会执行init方法(由字节码中是否跟随invokespecial指令决定),把对象按照程序员的意愿进行初始化。
二、对象的内存布局
在HotSpot虚拟机中,对象在内存中储存的布局可分为3块区域:对象头(Object Header)、实例数据(Instance Data)、对象填充(Object Padding)。
1、对象头包括两部分数据
- 存储对象自身的运行时数据,如下图

- 类型指针,即对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。
- 若对象是一个数组,在头信息还会记录一块数组长度的数据。
2、实例数据
存放对象真正有效信息,程序代码中所定义的各种类型的字段内容。无论是父类继承的还是子类定义的,都会记录起来。
3、对齐填充
不是必然存在的,仅仅起着占位符作用,因为HotSpot要求对象大小必须是8字节的整数倍。因此对象数据没有对齐时,就需要通过对其填充来补全。
三、对象的访问定位
对象访问取决于虚拟机,目前主流两种方式有句柄和直接指针两种。
- 句柄:Java堆会划分一块内存作为句柄池,reference中存储的是对象句柄的地址,句柄包含了对象的实例数据与类型数据的具体地址信息,如下图

- 指针:reference中存放的直接就是对象地址,如下图

两种方式各有优势
- 句柄方式就是稳定,在对象移动(垃圾回收时对象移动是很普遍的行为)时候,只会改变句柄中实例数据指针,reference不会修改。
- 指针就是速度快,节省了一次指针定位的开销,对象访问在Java中非常频繁,积少成多也是一笔非常可观的执行成本。HotSpot就采用的这种方式。
《深入理解java虚拟机》笔记(2)HotSpot虚拟机对象探秘的更多相关文章
- 深入理解Java内存模型中的虚拟机栈
深入理解Java内存模型中的虚拟机栈 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域,这些区域都会有各自的用途,以及创建和销毁的时间,有的区域会随着虚拟机进程的启 ...
- Java学习笔记之---类和对象
Java学习笔记之---类和对象 (一)类 类是一个模板,它描述一类对象的行为和状态 例如:动物类是一个类,动物们都有属性:颜色,动物们都有行为:吃饭 public class Dog { Stri ...
- Java 虚拟机 - 2.3 HotSpot虚拟机对象
对象的创建 Step1 类加载检查 当发现一条new指令时,检查: 该指令的参数是否能在常量池中定位到一个类的符号引用: 并且检查这个符号引用代表的类是否已经被加载.解析和初始化过.如果没有,那必须先 ...
- Java开发笔记(九十)对象序列化及其读写
有些时候,开发者想把程序运行过程中的数据临时保存到文件,可是前面介绍的字符流和字节流,要么用来读写文本字符串,要么用来读写字节数组,并不能直接保存某个对象信息,因为对象里面包括成员属性和成员方法,单就 ...
- Java学习笔记(2)--- 对象和类入门,java包,this 和 super区别
1.对象和类(Object and class): 一个 Java 程序可以认为是一系列对象的集合,而这些对象通过调用彼此的方法来协同工作. 面对对象编程是java非常重要的一部分,作者本身之前学过c ...
- Java学习笔记五 常用API对象一
常用API:字符串操作:String类,StringBuffer类,StringBulider类 字符串是最重要的数据类型之一,处理字符串也是一种语言的基本工作. 1.String类: public ...
- Java学习笔记 04 类和对象
一.类和对象的概念 类 >>具有相同属性和行为的一类实体 对象 >>实物存在的实体.通常会将对象划分为两个部分,即静态部分和动态部分.静态部分指的是不能动的部分,被称为属性,任 ...
- 深入理解JAVA I/O系列五:对象序列化
序列化 对象序列化的目标是将对象保存到磁盘中,或者允许在网络中直接传输对象.对象序列化机制允许把内存中的JAVA对象转换成跟平台无关的二进制流,从而允许将这种二进制流持久地保存在磁盘上,通过网络将这种 ...
- Java学习笔记9(面象对象9:多态)
多态概述 多态是继封装.继承后,面对对象的第三大特性. 现实事物经常会出现多态,如学生,学生是人的一种,则一个具体的同学张三既是学生也是人,即出现两种形态. Java作为面向对象的语言,同样可以描述一 ...
- Java 学习笔记 ------第五章 对象封装
本章学习目标: 了解封装的概念与实现 定义类.构造函数与方法 使用方法重载与不定长度自变量 了解static方法 一.Java封装概念 在面向对象程式设计方法中,封装(英语:Encapsulation ...
随机推荐
- POJ3264(线段树入门题)
Balanced LineupCrawling in process... Crawling failed Time Limit:5000MS Memory Limit:65536KB ...
- Python list的定义和删改
需要用到list.取回参数 . sys.argv返回的是个元组. 最后发现用for循环好像没用. a=0 for i in sys.argv[1:]: qh[a]=sys.argv[a] a=a+1 ...
- pow()函数的精度问题
妈蛋这个坑了我大半个小时都想不出个原因..后来看到pow的定义才想起,数据类型很重要啊.. 1.底数用常量,指数用整型 #include <stdio.h> #include <ma ...
- LeetCode: 371 Sum of Two Integers(easy)
题目: Calculate the sum of two integers a and b, but you are not allowed to use the operator + and -. ...
- Fiddler如何抓取HTTPS协议的网页
Fiddler默认只能抓取HTTP协议的网页,不能抓取HTTPS协议的网页,而我们很多时候,都需要抓HTTPS协议的网页,比如抓淘宝数据等.今天,韦玮老师会为大家讲解如何使用Fiddler抓取HTTP ...
- Oracle SQL调优之分区表
目录 一.分区表简介 二.分区表优势 三.分区表分类 3.1 范围分区 3.2 列表分区 3.3 散列分区 3.4 组合分区 四.分区相关操作 五.分区相关查询 附录:分区表索引失效的操作 一.分区表 ...
- 无监督学习:Linear Dimension Reduction(线性降维)
一 Unsupervised Learning 把Unsupervised Learning分为两大类: 化繁为简:有很多种input,进行抽象化处理,只有input没有output 无中生有:随机给 ...
- web测试与手机测试的区别
1.web是B/S,移动端是C/S 2.系统的性能: B/S的优势是异地浏览和信息采集比较灵活性,随时随地只要能使用浏览器上网即可 但是客户端只能完成浏览,查询,数据输入等简单工作,绝大部分又服务器承 ...
- android实现简单计算器
前台代码如下 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:andro ...
- js转义字符
\" \/ \" 例: span = "<span onclick=\"xadmin.open('编辑','\/junyi\/member\/up ...