对象访问的方式
不同的虚拟机的对象访问方式有所不同,主流的访问方式有两种:使用句柄间接访问实例数据、指针直接访问实例数据。
a)指针直接访问实例数据
在这种方式中,JVM栈中的栈帧中的本地变量表中所存储的引用地址就是实例数据的地址。通过这个引用就能直接获取到实例数据的地址。
除此之外,其实引用所指向的对内存中的对象数据有两部分组成,一部分就是这个对象实例本身,另一部分是对象类型在方法区中的地址。
b)使用句柄间接访问实例数据
JVM会在堆中划分一块内存来作为句柄池,JVM栈中的栈帧中的本地变量表中所存储的引用地址是这个对象所对应的句柄地址,而非对象本身的地址。句柄池中的一个个对象地址有两部分组成,一部分就是对象数据在堆内存中实例池中的地址,另一部分就是对象类型在方法区中的地址。
综上所述:句柄池就相当于一个中转站,我们要查询的实例对象数据需要通过一次间接索引获取;而指针的直接访问无需中转站,引用指向的就是要访问的实例对象数据。
此外,不管是哪种对象的访问方式,引用所指向的堆内存中的数据都是有两部分组成,其中有一部分一定是一个指向方法区中的对象类型的指针。
两种对象访问方式的好处
a)句柄访问对象的好处
访问对象通过一个句柄指针一次间接索引之后,当对象实例数据被移动的时候(垃圾回收的时候有些对象会被移动),只需要改变句柄池中该对象实例的地址即可,无需改变引用和句柄池的对应关系,所以引用中存储的是稳定的句柄地址。
b)指针直接访问对象的好处
这种方式最大的好处就是访问对象的速度很快,比通过句柄访问对象节约了一半的寻址时间,由于Java中对象的访问非常频繁,所以这种方式能节约很多寻址时间。