Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/154.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
对象如何存储在内存中-Java(c+;+;)_Java_C++ - Fatal编程技术网

对象如何存储在内存中-Java(c+;+;)

对象如何存储在内存中-Java(c+;+;),java,c++,Java,C++,我有一个关于用java语言创建对象的内存问题 当一个人用java创建一个对象时,堆上的某个内存空间被占用了,对吗?但这段记忆的一部分是什么?是membervariables还是membervariables和methods?会不会是引用同一类的多个对象共享了一些东西 假设我有下面的课程 class MyClass { //Membervariables protected int age; protected long dateOfBirth; /*

我有一个关于用java语言创建对象的内存问题

当一个人用java创建一个对象时,堆上的某个内存空间被占用了,对吗?但这段记忆的一部分是什么?是membervariables还是membervariables和methods?会不会是引用同一类的多个对象共享了一些东西

假设我有下面的课程

 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;
    }
  }
因此,在本课程中,我有以下几点: -两个成员变量-一个int和一个long

  • 一个构造器

  • 一种变异方法

  • 一个访问器方法

在main方法中,我创建了此类的两个实例(对象):

 MyClass myClass1 = new MyClass(10);
 MyClass myClass2 = new MyClass(11);
所以我的问题是:

1) 如何在计算机内存中描述这一点

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


提前感谢

对象数据放在堆上,类数据和成员函数共享

Java语言规范没有指定堆布局。实际上,大多数Java对象将至少有一个“vtable指针”(术语有问题),它指向方法向量表(可能是方法指针,但也可能是一系列“跳转”指令)和其他运行时类型信息,然后是数据成员。因此,在您的示例中,对象的堆布局可能如下所示:

(4 bytes) vtable pointer (points to MyClass vtable)
(4 bytes) age
(8 bytes) date of birth
对于同一类的任意两个对象,vtable指针应具有相同的值。因此,方法向量表和方法本身在地址空间中只存在一次

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


关于问题的第二部分,C++使用相同的技术;但是,堆布局在语言规范中没有完全指定。当然C++中的对象不必存储在堆上(当某些优化进入其中时,java中的对象也是如此)。但对象的内存布局通常不依赖于它的分配位置。

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

方法的位置是通过跟踪指向该类的类指针并在内部类对象中索引方法表来确定的

在64位JVM中,上面的对象大致如下:

  • 类指针-8字节
  • 锁变量-8字节
  • GC标志-4字节
  • 散列值-4字节
  • 出生日期-8字节
  • 年龄-4字节
总共36字节。(当然,在32位JVM中更少。)36字节可能会被舍入到48字节以将其置于16字节边界上,或者至少40字节以将其置于8字节边界上

(这是一种可能的实现。有一些技巧可以用来减少/组合lock和GC字段的空间,例如,但基本原则适用。)

当一个人用java创建一个对象时,堆上的某个内存空间被占用了,对吗

可能吧,但是JVM可以将它放在堆栈上,或者完全优化它

但这段记忆的一部分是什么

如果您有世代收集器,则小对象将放置在Eden空间中,而大对象将放置在终身空间中

是membervariables还是membervariables和methods

只是变量。对象有一个指向类的链接,该类包含所有加载的方法

会不会是引用同一类的多个对象共享了一些东西

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

1) 如何在计算机内存中描述这一点

64位JVM有一个16字节的头,其中包括哈希代码和对类的引用。然后是字段。为了提高内存访问,更宽的字段一起出现,以减少所需的填充量

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


<>对于具有虚拟方法的C++对象,它们也将有一个链接到VTABLE。

java语言规范并没有指定这些东西。这取决于每个JVM实现..身份哈希代码在哪里?我相信它比这更紧凑,尽管有很多对齐方式。@TomHawtin tackline-是的,我忘了散列。我相信我所看到的版本,它与GC标志共享空间。没有锁字段有多种方法,通常是以一种奇怪的方式将其与类指针交换。对象头比这个小。。。我理解。例如,仅在需要时存储完整标识散列;e、 g.如果调用了
identityHashcode(obj)
,然后该对象存活下来,然后是下一个GC。锁和类“指针”不需要是完全引用。有时使用的一个技巧是将一个扩展指针用于锁定和散列。另一种方法是,如果对象需要锁定或散列(这两种方法都很少见),则“扩展”对象,并在对象的末尾放置新字段。不要让人感到困惑<代码>C++使用了完全不同的方法。
C++
中的对象是内存本身,而不是它的引用/句柄。@qwm-不确定您的意思;我在这里非常具体地谈论堆布局,这就是问题所要问的。那么您很可能没有回答这个问题。问题是代码>存储在对象内存中的对象< /COD>,C++中与堆无关。我只是想让你把答案编辑得更具体一些。我已经编辑过了,尽管我认为