2014-01-27 49 views
2

我有一个关于用java语言创建对象的内存问题。如何将对象存储在内存中 - Java(C++)

当在java中创建一个对象时,某个内存空间在堆上被占用 - 对吗?但是这个记忆的一部分是什么?它是成员变量还是成员变量和方法?是否可以让几个指向同一个类的对象共享一些东西?

让说我有下面的类

class MyClass { 

    //Membervariables 
    protected int age; 
    protected long dateOfBirth; 


    /** 
    * Constructor 
    * @param age 
    */ 
    public MyClass(int age) { 
     this.age = age; 
    } 


    /** 
    * 
    * @param dateOfBirth 
    */ 
    protected void setDob(long dateOfBirth) { 
     this.dateOfBirth = dateOfBirth; 
    } 


    /** 
    * 
    * @return 
    */ 
    protected int getAge() { 
     return this.age; 
    } 


    /** 
    * 
    * @return 
    */ 
    protected long getDob() { 
     return this.dateOfBirth; 
    } 
    } 

所以在这个班,我有以下: - 两个membervariables - 一个INT和一个

  • 一个构造函数

  • 一个mutator-method

  • one accessor-method。

在主方法创建这个类的两个实例(对象):

MyClass myClass1 = new MyClass(10); 
MyClass myClass2 = new MyClass(11); 

所以我的问题是:

1)这个怎么会在计算机上描绘记忆?

2)关于对象在内存中存储事物的相同“体系结构”是否也可以应用于C++?

在此先感谢!

+1

Java语言规范没有规定这样的事情。这取决于每个JVM的实现。 –

回答

1

对象数据的推移堆,类数据和成员函数共享

1

Java语言规范没有指定堆布局。实际上,大多数Java对象至少会有一个“vtable指针”(术语可疑)指向一个方法向量表(可能是方法指针,但也可能是一系列'跳转'指令)时间类型信息,然后是数据成员。所以,你的榜样,对象堆布局可能看起来像:

(4 bytes) vtable pointer (points to MyClass vtable) 
(4 bytes) age 
(8 bytes) date of birth 

对于同一类的任何两个对象,虚函数表指针应具有相同的价值。所以,方法向量表和方法本身在地址空间中只出现一次。

请记住,这只是一个(简化)示例,Java的实现不需要坚持这一点。

关于您的问题的第二部分,C++使用相同的技术;但是,再次,堆布局未在语言规范中完全指定。当然,C++中的对象不一定需要存储在堆中(当某些优化开始时,Java中也是如此),但是对象的内存布局通常不依赖于它的分配位置。

+0

不要混淆人。 'C++'使用根本不同的方法。 'C++'中的对象是内存本身,而不是它的引用/句柄。 – qwm

+0

@qwm - 不确定你的意思;我在这里特别谈论堆布局,这就是问题所在。 – davmac

+0

那么你很可能不会回答这个问题。问题是“事物如何存储在关于对象的内存中”,而在C++中它与堆无关。只是想让你编​​辑你的答案更具体。 – qwm

3

一个对象由一个指向该类内部版本的指针,一个用于​​锁定的区域,一个GC标志区域以及该类中定义的实例字段组成。(请注意,对象引用字段只是一个指针 - 被引用的对象是分开分配的。)

方法通过跟随指向类的类指针和索引内部类对象中的方法表来定位。

你的对象的上方,在一个64位的JVM,将大致:

  • 类指针 - 8个字节
  • 锁变量 - 8个字节
  • GC标志 - 4个字节
  • 哈希值 - 4个字节
  • DATEOFBIRTH - 8字节
  • 年龄 - 4个字节

总共36个字节。 (当然,在32位JVM中的数量更少)。36个字节可能会四舍五入为48个字节,以将其放在16字节的边界上,或者至少40个字节放在8个字节的边界上。

(这是一个可行的实施方式有许多可以被用来减少/换锁和GC领域相结合的空间,如技巧,但基本原则适用。)

+0

你身份哈希码在哪里?我相信它往往比这更紧凑,尽管有很多路线。 –

+0

@ TomHawtin-tackline - 是的,我忘了哈希。我相信我看到它与GC标志共享空间的版本。 –

+0

还有很多方法可以在没有锁定字段的情况下完成,通常通过以奇怪的方式将它与类指针交换。 –

1

当一个人创建在java中的对象堆中占用了一定的内存空间 - 正确吗?

也许,但JVM可以将它放在堆栈上或完全将其优化。

但是这部分内存是什么?

如果您有一个世代收藏家,小物体被放置在伊甸园空间和大型物体被放置在终身空间。

它是成员变量还是成员变量和方法?

只是变量。该对象具有指向保存所有加载方法的类的链接。

难道是因为几个指向同一类的对象共享一些东西?

是的,当然。但这不是要求,只是更优化的解决方案。

1)这怎么可能在计算机内存中被描述?

64位JVM有一个16字节的头文件,其中包含hashCode和对该类的引用。接下来是字段。为了改善内存访问,更广泛的字段一起出现以减少所需填充量。

2)关于物体在物体存储器中物体存储的相同“体系结构”是否也适用于C++?

对于具有虚拟方法的C++对象,它们也将链接到vtable。

相关问题