java对象的访问定位方式

	java对象在访问的时候,我们需要通过java虚拟机栈的reference类型的数据去操作具体的对象。由于reference类型在java虚拟机规范中只规定了一个对象的引用,并没有定义这个这个引用应该通过那种方式去定位、访问java堆中的具体对象实例,所以一般的访问方式也是取决与java虚拟机的类型。目前主流的访问方式有通过句柄和直接指针两种方式。

1.句柄访问


	使用句柄访问方式,java堆将会划分出来一部分内存去来作为句柄池,reference中存储的就是对象的句柄地址。而句柄中则包含对象实例数据的地址和对象类型数据(如对象的类型,实现的接口、方法、父类、field等)的具体地址信息。下边我以一个例子来简单的说明一下:
	Object obj = new Object();
	Object obj表示一个本地引用,存储在java栈的本地便变量表中,表示一个reference类型的数据。
		new Object()作为实例对象存放在java堆中,同时java堆中还存储了Object类的信息(对象类型、实现接口、方法等)的具体地址信息,这些地址信息所执行的数据类型存储在方法区中。

2. 直接指针访问

		如果使用指针访问,那么java堆对象的布局中就必须考虑如何放置访问类型的相关信息(如对象的类型,实现的接口、方法、父类、field等),而reference中存储的就是对象的地址。
		这两种访问方式各有利弊,使用句柄访最大的好处是reference中存储着稳定的句柄地址,当对象移动之后(垃圾收集时移动对象是非常普遍的行为),只需要改变句柄中的对象实例地址即可,reference不用修改。
		使用指针访问的好处是访问速度快,它减少了一次指针定位的时间开销,由于java是面向对象的语言,在开发中java对象的访问非常的频繁,因此这类开销积少成多也是非常可观的,反之则提升访问速度。
本文参考《深入理解java虚拟机 JVM高级特性与最佳实践》一书。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-09 04:04:32

java对象的访问定位方式的相关文章

Java对象的访问定位

java对象在访问的时候,我们需要通过java虚拟机栈的reference类型的数据去操作具体的对象.由于reference类型在java虚拟机规范中只规定了一个对象的引用,并没有定义这个这个引用应该通过那种方式去定位.访问java堆中的具体对象实例,所以一般的访问方式也是取决与java虚拟机的类型.目前主流的访问方式有通过句柄和直接指针两种方式. 1.句柄访问 使用句柄访问方式,java堆将会划分出来一部分内存去来作为句柄池,reference中存储的就是对象的句柄地址.而句柄中则包含对象实例

Java对象的内存布局以及对象的访问定位

先来看看Java对象在内存中的布局 一 Java对象的内存布局 在HotSpot虚拟机中,对象在内存中的布局分为3个区域 对象头(Header) Mark Word(在32bit和64bit虚拟机上长度分别为32bit和64bit)存储对象自身的运行时数据,包括哈希码,GC分代年龄,锁状态标志,线程持有的锁,偏向线程ID,偏向时 间戳等 类型指针 即对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例.但是并不是所有类型虚拟机实现都必须在对象数据上保留类型指针,如果对象是一

jvm学习记录-对象的创建、对象的内存布局、对象的访问定位

简述 今天继续写<深入理解java虚拟机>的对象创建的理解.这次和上次隔的时间有些长,是因为有些东西确实不好理解,就查阅各种资料,然后弄明白了才来做记录. (此文中所阐述的内容都是以HotSpot虚拟机为例的.) 对象的创建 java程序在运行过程中无时无刻都有对象被创建出来,那么创建对象是个怎么样的过程呢?还是看看我自己的理解吧. 判断是否已经执行类加载 当虚拟机遇到一条new指令时 ,首先去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已经被加载

创建对象的过程及对象的访问定位

对象的创建 对象创建的几种方式 一. 用new来创建 二. 克隆 三. Class对象和Constructor中的newInstance()方法 四. 反序列化 对象创建的过程(不包括数组对象和Class对象的创建) 一. 类加载,如果该对象对应的类还没有被加载到内存中则会就行类的加载,可能会涉及到父类的加载(具体看类的加载过程) 二. 分配内存,当类加载完成后对象所需的内存就可以确定,就可以为其分配内存,在内存分配时有两种方法: 1. 指针碰撞法:将指针作为已经分配内存和未分配内存的分界线,当

Java对象大小的计算方式

Java对象大小的计算方式首先我们需要知道的是 Java 对象是包含三部分数据的:?1.对象头?2.实例数据?3.对齐填充(可能没有,因为 java 中规定对象的起始地址必须是 8 bytes 的正数倍)? 对于普通对象而言,对象头中包括 mark word(8 bytes).kclass(没有开启压缩的时候是 8 bytes,开启压缩了的话,就是 4 bytes),如果是数组类型的对象话,这里还有一个数组长度字段,4字节.? 在 JDK6 64位 23 update+ 之后都默认开启了指针压缩

Java对象的访问方式

Java对象在虚拟机中有两种访问方式: 通过句柄访问对象 Java堆中有一块内存为句柄池 Java本地栈中的reference存储的是句柄池中的句柄地址 句柄中包含了对象实例数据地址(堆中的实例池)和对象类型数据地址(方法区) 通过指针访问对象 reference中存储的是对象地址 对象中存储类型数据地址 优缺点: 句柄的存储比较稳定,对象的移动不影响reference 指针的好处是速度快,节省了一次指针定位的时间开销

读《jvm虚拟机》 - 对象的访问定位

上一篇看了堆内存是怎么创建对象的,那么创建完肯定要使用对象啦~ 那是怎么访问对象呢? java 程序是通过栈上的reference数据来操作堆上的具体对象的. 首先我们回顾一下虚拟机栈: 虚拟机栈是 java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧(Stack Frame)用于存储局部变量表.操作数栈.动态链接.方法出口等信息. 局部变量表存放了编译期可知的各种基本数据类型(long,boolean,int,byte,short,long,double,float).return

java 对象参数去空格方式

import java.lang.reflect.Field; import java.lang.reflect.Method; public class Test { /** * 去掉bean中所有属性为字符串的前后空格 * * @param bean * @throws Exception */ public static void beanAttributeValueTrim(Object bean) throws Exception { if (bean != null) { //获取所

JVM笔记5-对象的访问定位。

java虚拟机中指定一个栈内存的引用指向了堆内存中的对象.这样说只是笼统的说法.而指向堆内存中的对象就一定是栈引用所需要的那个对象吗?其实并不定. 这就需要知道对象的访问定位方式有两种: 1.使用句柄.所谓的句柄其实就是堆内存中分配一块内存记录对象实例的指针和对象类型数据的指针,而对象类型数据区域是在方法区中的.这样栈引用第一步先指向堆中 的句柄.第二步根据句柄中的对象实例的指针和对象类型数据的指针找到对应的对象实例和其类型数据.虽然这里用了两步,必然对于使用直接指针来说,效率必然会慢.因为 这