大多数文章中都会列举如下两张图的内容但是解析不够详细在这里详细解释一下两张图的含义

基于句柄的内存定位方式

wKiom1LTsuyzf7oKAADRfcx_iWk117.jpg

基于指针的内存定位方式

wKioL1LTst_RN1hVAAC6OSYCXUM758.jpg

java栈是针对每一个线程的,每一个线程都会有自己的栈,维护在其内部的引用就是本地变量表。

在java中每一个reference只是指向了一个内存块,其中并没有实例对象的内容,因此可能会出现这种情况:同一个线程多个引用只想了同一个内存地址,不同线程的引用指向了同一个内存地址。

因此当gc进行内存清理时,若将在java堆中的对象进行了移动,那么对于基于指针的对象定位方式就需要将他内部的全部引用进行更新,更新次数较多。但是基于句柄的更新方式则不同,由于全部对象都指向了一个句柄,而句柄中维护了一个指向对象的指针,因此在进行内存整理时,只需要更新句柄中实例的内容就可以了。

当进行对象访问时,基于指针的对象定位方式可以直接获取到对象的内容,但是基于句柄的需要两步才能获取到对象内容,时间上有所损失。