一版做完下一版,
需求太多怎么办,
申请元旦来加班,
三倍工资不想赚。
------------------打油诗分割线-----------------
本文内容以HotSpot虚拟机为例,其他jvm需根据情况自行判断。
上文学习了内存模型,顺带也学习下对象的情况,jvm中,对象的使用占据了绝大部分场景,需要至少做个大概了解。
对象包含对象头(Header),数据实例(Instance Data)及对齐填充(Padding)。
对象头分为两部分:
1.Mark Word,记录对象运行时数据,包括hashcode,GC分代年龄,锁状态,线程持有的锁,偏向线程ID,偏向时间戳等。根据jvm的位数,长度分别为32bit和64bit(未压缩指针)
2.类型指针,对象指向它的类元数据的指针,通过该指针来确定对象是哪个类的实例。
数据实例的部分:
真正对象的存储数据,一般来说,长度相同的数据会被jvm分配到一起。
对其填充:
占位符,不一定存在,只是为了让对象的大小是8字节的整数倍,满足HotSpot对内存管理的要求。
对象的访问:
在Java 语言中,对象访问是如何进行的?
对象访问在Java 语言中无处不在,是最普通的程序行为,但即使是最简单的访问,也会却涉及Java 栈、Java 堆、方法区这三个最重要内存区。
如下面的这句代码:
Object obj = new Object();
假设这句代码出现在方法体中,那“Object obj”这部分的语义将会反映到Java 栈的局部变量表中,作为一个reference 类型数据出现,并指向堆中对象实例的地址。
而“new Object()”这部分的语义将会反映到Java 堆中,形成一块存储了Object 类型所有实例数据值(Instance Data)的内存,根据具体类型以及虚拟机实现的对象内存布局的不同,这块内存的长度是不固定的。
另外,在Java 堆中还必须包含能查找到此对象类型数据(如对象类型、父类、实现的接口、方法等)的地址信息,而这些类型数据则存储在方法区中。
由于reference 类型在Java 虚拟机规范里面只规定了一个指向对象的引用,并没有定义这个引用应该通过哪种方式去定位,以及访问到Java 堆中的对象的具体位置,因此
不同虚拟机实现的对象访问方式会有所不同,主流的访问方式有两种:使用句柄和直接指针。
如下图是HotSpot使用直接指针的访问方式:
直接指针访问