[英]How objects are stored in memory - Java (c++)
我有一个关于在Java语言中创建对象的内存问题。
当在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;
}
}
因此,在该类中,我具有以下内容:-两个成员变量-一个int和一个long
一个构造函数
一种变法
一种访问方法。
在主要方法中,我创建此类的两个实例(对象):
MyClass myClass1 = new MyClass(10);
MyClass myClass2 = new MyClass(11);
所以我的问题是:
1)如何在计算机内存中进行描述?
2)是否可以将与对象有关的事物存储在内存中的相同“架构”也应用于c ++?
提前致谢!!!
对象由指向类的内部版本的指针,用于synchronized
锁定的区域,GC标志的区域以及在类中定义的实例字段组成。 (请注意,对象引用字段只是一个指针-被引用的对象是单独分配的。)
通过跟随指向类的类指针并在内部类对象中索引方法表来定位方法。
在64位JVM中,您上面的对象大致为:
总共36个字节。 (当然,在32位JVM中较少。)这36个字节可能会四舍五入为48个字节,以将其置于16字节边界,或者至少为40个以将其置于8字节边界。
(这是一种可能的实现。可以使用一些技巧来减少/合并用于lock和GC字段的空间,例如,但是基本原理适用。)
对象数据在堆上,类数据和成员函数共享
Java语言规范未指定堆布局。 实际上,大多数Java对象将至少具有一个“ vtable指针”(术语可疑),该指针指向方法向量表(可能是方法指针,但也很有可能是一系列的“跳转”指令)和其他运行-时间类型信息,然后是数据成员。 因此,以您的示例为例,对象的堆布局可能类似于:
(4 bytes) vtable pointer (points to MyClass vtable)
(4 bytes) age
(8 bytes) date of birth
对于同一类的任何两个对象,vtable指针应具有相同的值。 因此,方法向量表以及方法本身在地址空间中仅存在一次。
请记住,这只是一个(简化的)示例,Java的实现不必遵循此示例。
关于问题的第二部分,C ++使用相同的技术。 但是同样,语言规范没有完全指定堆布局。 当然,C ++中的对象不必一定存储在堆上(当某些优化起作用时,在Java中也是如此),但是对象的内存布局通常并不依赖于其分配位置。
当在Java中创建一个对象时,堆上会占用一定的内存空间-对吗?
可能是,但是JVM可以将其放在堆栈上或完全对其进行优化。
但是这个记忆是什么呢?
如果您有分代收集器,则将小对象放置在伊甸园空间中,将大对象放置在使用权空间中。
是成员变量还是成员变量和方法?
只是变量。 该对象具有指向包含所有已加载方法的类的链接。
可能是几个引用同一类的对象共享某些东西吗?
当然是。 但这不是必需的,只是一个最佳的解决方案。
1)如何在计算机内存中进行描述?
64位JVM具有16字节的标头,其中包含hashCode和对该类的引用。 接下来是字段。 为了改善内存访问,较宽的字段会一起出现,以减少所需的填充量。
2)是否可以将与对象有关的事物存储在内存中的相同“架构”也应用于c ++?
对于具有虚拟方法的C ++对象,它们还将具有指向vtable的链接。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.