目录
建立对象是为了使用对象,而使用对象是通过引用来实现的,而引用(reference)一般是存在JVM栈中的局部变量表中的。
由于reference类型在Java虚拟机规范中只规定了一个指向对象的引用,并没有定义这个引用应该通过何种方式去定位、
访问堆中的对象的具体地址,所以对象访问方式也是取决于虚拟机实现而定的。目前主流的访问方式有使用句柄和直接指针两种。
一、使用句柄访问
若是使用句柄访问方法的话,那么在堆内存中就会划分一块空间来作为句柄池,引用reference存储的就是对象的句柄地址,而句柄包含了对象实例的数据的地址和对象类型数据的地址。就是说通过句柄可以找到对象实体和对象所属于的类型。(对象一般创建在 堆中,而方法区存放的是类的信息)
(本地本量表=局部变量表)
二、使用直接指针访问
如果使用指针访问,那么reference中存储的就直接是对象的地址。
三、两种方式的比较
各有优势。
使用句柄访问的好处就是:引用reference中存储的是最稳定的句柄地址,因为无论对象怎么移动(垃圾收集时移动对象是非常普遍的行为),修改的是句柄中的实例数据指针,而reference本身不需要修改。但是需要三次指针定位操作,一次是寻找对应的句柄,一次寻找对象数据,一次是寻找对象类型。
使用直接指针访问的好处是:速度更快,因为它对比句柄访问,少做了一次指针定位操作。由于对象的访问在Java中非常频繁,因此这类开销积少成多后也是一项非常可观的执行成本。
而最常用的HotSpot虚拟机就是用第二种方式的。