13

当一个类实例化以下对象时,内存中会发生什么?

public class SomeObject{

    private String strSomeProperty;

    public SomeObject(String strSomeProperty){
        this.strSomeProperty = strSomeProperty;
    }
    public void setSomeProperty(String strSomeProperty){
        this.strSomeProperty = strSomeProperty;
    }
    public String getSomeProperty(){
        return this.strSomeProperty;
    }
}

在课堂上SomeClass1

SomeObject so1 = new SomeObject("some property value");

在课堂上SomeClass2

SomeObject so2 = new SomeObject("another property value");

如何为新实例化的对象及其属性分配内存?

4

3 回答 3

12

让我们一步一步来:

SomeObject so1 = new SomeObject("some property value");

...实际上比看起来更复杂,因为您正在创建一个新字符串。可能更容易想到:

String tmp = new String("some property value");
SomeObject so1 = new SomeObject(tmp);
// Not that you would normally write it in this way.

(绝对准确 - 这些并不是真正等效的。在原始版本中,“新字符串”是在编译时创建的,并且是 .class 图像的一部分。您可以将其视为性能黑客。)

因此,首先 JVM 为字符串分配空间。您通常不知道或不关心 String 实现的内部结构,因此请相信一块内存正在用于表示“某些属性值”。此外,您还临时分配了一些内存,其中包含对字符串的引用。在第二种形式中,它被显式调用tmp;在您的原始形式中,Java 处理它而不命名它。

接下来,JVM 为新的 SomeObject 分配空间。这是 Java 内部簿记的一点空间,也是每个对象字段的空间。在这种情况下,只有一个字段strSomeProperty.

请记住,这strSomeProperty只是对字符串的引用。现在,它将被初始化为 null。

接下来,执行构造函数。

this.strSomeProperty = strSomeProperty;

所有这一切都是将对字符串的引用复制到您的strSomeProperty字段中。

最后,为对象引用分配空间so1。这是通过对 SomeObject 的引用设置的。

so2以完全相同的方式工作。

于 2008-11-26T15:17:24.770 回答
7

Heinz M. Kabutz 博士的 Determining Memory Usage in Java给出了一个精确的答案,以及一个计算内存使用量的程序。相关部分:

  1. 该类至少占用 8 个字节。所以,如果你说 new Object(); 您将在堆上分配 8 个字节。
  2. 每个数据成员占用 4 个字节,除了 long 和 double 占用 8 个字节。即使数据成员是一个字节,它仍然会占用4个字节!此外,使用的内存量以 8 字节块的形式增加。因此,如果您有一个包含一个字节的类,它将占用该类的 8 个字节和用于数据的 8 个字节,总共 16 个字节(呻吟!)。
  3. 数组更聪明一点。基元被打包在数组中,所以如果你有一个字节数组,它们每个都会占用一个字节(哇!)。当然,内存使用量仍以 8 字节块的形式增加。

正如人们在评论中指出的那样,字符串是一种特殊情况,因为它们可以被实习。您可以以相同的方式推断它们占用的空间,但请记住,看起来同一个 String 的多个副本实际上可能指向同一个引用。

于 2008-11-26T17:07:54.253 回答
3

要记住的要点:

  1. 调用方法时,会在堆栈顶部创建一个框架。
  2. 一旦方法完成执行,控制流将返回到调用方法,并刷新其相应的堆栈帧。
  3. 局部变量在堆栈中创建。
  4. 实例变量是在堆中创建的,并且是它们所属对象的一部分。
  5. 引用变量在堆栈中创建。

参考:http ://www.javatutorialhub.com/java-stack-heap.html

于 2012-08-28T09:38:59.753 回答