【问题标题】:Do java objects share method location in memory?java对象是否共享内存中的方法位置?
【发布时间】:2014-03-20 00:30:23
【问题描述】:

考虑这个类:

public class Test {
    private int bar = 5;

    public void foo () {
        System.out.println("hi");
    }
}

现在假设我们正在执行以下代码部分:

Test obj1 = new Test();
Test obj2 = new Test();
Test obj3 = new Test();

所有三个对象都存在于同一范围内。因为 bar 不是静态的,所以内存中会有三个单独的 bar 实例。

  1. 内存中有 foo 方法的三个实例吗?

  2. JVM 是否做了一些魔法让每个对象都可以在内存中使用一个方法声明?

  3. 是否有这种情况的名称,以便我可以查看其他语言是否这样做?

【问题讨论】:

    标签: java oop object memory


    【解决方案1】:

    方法由索引引用,没有方法的实例,即它们不占用额外的内存。

    负责处理基于类的方法的Java指令集是invokevirtual

    http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5.invokevirtual

    这里更详细地介绍了引擎盖下发生的事情(解释得比我能做的好得多):

    http://zeroturnaround.com/rebellabs/java-bytecode-fundamentals-using-objects-and-calling-methods/


    其他参考

    How the hava virtual machine handles method invocation and return

    这是一个类似的 SO 问题: How much memory is used for function references in a Java object?

    【讨论】:

    • 方法被索引引用,而不是指针引用,正如你自己的 JVM 规范引用状态。
    • 感谢您的更正,这是一个失误 - 我编辑了我的答案
    【解决方案2】:

    内存中有 foo 方法的三个实例吗?

    没有。

    JVM 是否做了一些魔法让每个对象都可以在内存中使用一个方法声明?

    没有。

    是否有这种情况的名称,以便我可以查看其他语言是否这样做?

    是什么让您认为其他语言可以做到这一点?这里真正的问题是为什么你认为方法会被实例化?有什么意义?

    【讨论】:

    • 你能解释一下为什么 1 和 2 都不是吗?
    • 你能指导我了解这是什么以及它是如何工作的吗?好像是优化,但是不知道要搜索什么。
    • @user13482 这不是“优化”,它只是类中保存的事物与实例中保存的事物之间的区别。这同样适用于静态成员变量。如果您想了解更多信息,请参阅 Java 虚拟机规范中的 Java 类文件格式文档。
    【解决方案3】:

    更清楚地说,不同的对象绝对没有必要为它们的方法使用不同的代码。假设您有 3 个 Test 实例,您需要 'bar' 成员的三个版本,因为它们可以有不同的值。然而,所有三个 'foo' 方法都做同样的事情。代表代码的位是完全相同的。拥有三个(相同的)版本将完全没有意义。

    所有其他计算机语言也这样做。事实上你会发现,在计算机上,如果你同时对三个文档执行(比如说)一个文本编辑器,将会有三个数据区域代表三个文档,但内存中只有一个地方是应用程序的实际代码被储存了。三个“实例”共享它。

    【讨论】:

      猜你喜欢
      • 2011-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-13
      相关资源
      最近更新 更多