4

指针只是用于实现java引用变量还是它是如何真正实现的?以下是Java语言规范中的行

4.3.1 对象 对象是类实例或数组。引用值(通常只是引用)是指向这些对象的指针,以及一个特殊的空引用,它不引用任何对象。

这是否意味着它一直是指针?

4

5 回答 5

7

在现代 JVM 中,引用被实现为地址。

回到 HotSpot 的第一个版本(以及更早的“经典 VM”),引用被实现为句柄。那是一个指向指针的固定指针。对于任何特定对象,第一个指针永远不会改变,但随着对象数据本身的移动,第二个指针会发生变化。显然这会影响使用中的性能,但更容易为其编写 GC。

在 JDK7 的最新版本中,支持“压缩 oops”。我相信 BEA JRockit 已经有一段时间了。迁移到 64 位系统需要两倍的内存和地址带宽。“压缩 oops”利用地址的最低有效三或四位始终为零。32 位数据左移 3 位或 4 位,允许 32 或 64 GB 的堆而不是 4 GB。

于 2009-10-15T18:46:12.980 回答
2

您实际上可以从这里获取源代码:http: //download.java.net/jdk6/source/

对您的问题的简短回答是:是的,有一个指向您的 java 变量的内存位置的指针(还有一点额外的)。然而,这是一个巨大的过度简化。在 VM 中移动 java 变量涉及到很多很多 C++ 对象。如果你想弄脏看看hotspot\src\share\vm\oops 包。

在实践中,这对开发 Java 无关紧要,因为您没有直接使用它的方法(其次,您不希望这样做,JVM 已针对各种处理器架构进行了优化)。

于 2009-10-15T18:08:37.797 回答
1

答案将取决于每个 JVM 实现,但将其视为句柄的最佳方式。它是 JVM 可以在表或其他一些此类实现中查找引用的内存位置的值。这样,JVM 可以在垃圾回收期间在内存中移动对象,而无需更改内存指针。

于 2009-10-15T18:08:03.200 回答
0

原始类型始终按值传递。其中作为类变量实际上是对象的引用变量。

考虑一个原始类型:

int i=0; 

现在这个原始类型的值存储在地址 2068 的内存位置。每次使用这个原始类型作为参数时,都会创建一个新副本,因为它不是按引用传递而是按值传递。

现在考虑一个类变量:

MyClass C1 = new MyClass();

现在这将创建一个具有变量名称 C1 的类类型 MyClass 的对象。

类变量 C1 包含链接到 Valriable C1 的对象的内存位置的地址。所以基本上类变量 C1 指向对象位置(new MyClass())。

原始类型存储在堆栈中,对象存储在堆中。

于 2012-07-08T09:36:37.863 回答
-2

这是否意味着它一直是指针?

是的,但它不能像您在 C 中通常那样进行操作。

请记住,作为 Java 是一种依赖于其 VM 的不同编程语言,这个概念(指针)应该仅用作类比,以更好地理解此类工件的行为。

于 2009-10-15T18:14:40.377 回答