【问题标题】:How is reference to java object is implemented?如何实现对 java 对象的引用?
【发布时间】:2010-12-07 03:17:34
【问题描述】:

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

4.3.1 对象 对象是类实例或数组。参考资料 值(通常只是参考)是 指向这些对象的指针,以及 特殊的空引用,它指的是 没有对象。

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

【问题讨论】:

标签: java object reference implementation


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

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

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

    实际上,这对开发 java 来说并不重要,因为您没有直接使用它的方法(其次,您不希望这样做,JVM 已针对各种处理器架构进行了优化)。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

        考虑一个原始类型:

        int i=0; 
        

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

        现在考虑一个类变量:

        MyClass C1 = new MyClass();
        

        现在这将创建一个 MyClass 类类型的对象,其变量名为 C1。

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

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

        【讨论】:

          【解决方案5】:

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

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-02-28
            • 1970-01-01
            • 2023-01-10
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多