代码之家  ›  专栏  ›  技术社区  ›  Sajal Dutta

Java对象内存分配过程中的步骤

  •  12
  • Sajal Dutta  · 技术社区  · 16 年前

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

    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");
    

    3 回复  |  直到 4 年前
        1
  •  12
  •   slim    16 年前

    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映像的一部分。您可以将其视为性能攻击。)

    tmp

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

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

    接下来,执行构造函数。

    this.strSomeProperty = strSomeProperty;
    

    所有这些只是复制 参考 到字符串,到您的 strSomeProperty 领域

    so1

    so2 工作原理完全相同。

        2
  •  7
  •   Craig P. Motlin    13 年前

    Determining Memory Usage in Java

    1. 该类至少占用8个字节。所以,如果你说newobject();您将在堆上分配8个字节。
    2. 每个数据成员占用4个字节,除了long和double占用8个字节。即使数据成员是一个字节,它仍将占用4个字节!此外,使用的内存量以8字节块的形式增加。因此,如果您有一个包含一个字节的类,那么该类将占用8个字节,数据占用8个字节,总计16个字节(唉!)。

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

        3
  •  3
  •   Mihai Iorga    12 年前

    要记住的要点:

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

    裁判: http://www.javatutorialhub.com/java-stack-heap.html