引用不指向内存
Java引用不是指针。 它们包含某种指针数据或某些指针数据,因为它们来自当今计算机体系结构的本质,但这完全取决于JVM实现,它存储在参考值中以及如何访问它所引用的对象。 尽管不是很有效的实现,但是拥有一个巨大的指针数组(每个指针指向JVM的一个对象),并且引用是该数组的索引,这绝对是可以的。
实际上,JVM将引用实现为一种指针混合,其中某些位是标志,而某些位“指向”相对于某个区域的某个内存位置。
JVM为什么这样做而不是指针?
原因是垃圾回收。 为了实现有效的垃圾回收并避免内存碎片,JVM定期在内存中移动对象。 当由不再被引用的对象占用的内存被释放并且我们恰好在一个巨大的可用内存块中间有一个仍在使用和引用的小对象时,我们不希望该内存块被拆分。 而是,JVM将对象移动到另一个内存区域,并更新对该对象的所有引用以跟踪新位置。 一些GC实现会在发生这些更新时停止其他Java线程,以便没有Java代码使用未更新的引用而是移动了对象。 其他GC实现与底层OS虚拟内存管理集成在一起,从而在发生此类访问时导致页面错误,从而避免了应用程序线程的停止。
但是,问题是引用不是指针,而是JVM实现如何管理所有这些情况的责任。