该对象的内存看起来如何? [英] How would the memory look like for this object?
问题描述
我想知道此类(其对象)的内存布局如何:
class MyClass{字符串myString;int myInt;公共MyClass(string str,int i){myString = str;myInt = i;}}MyClass obj = new MyClass("hello",42);
有人可以想象吗?
更新:
基于奥利维尔·罗吉尔(Olivier Rogier)的回答以及ckuri和乔恩·斯凯特(Jon Skeet)的评论,我试图提出一个受
我不想进入最后的细节,但是我仍然对此感到好奇:
-
如果应访问
obj.myString
,是否需要两个查找",例如首先查找obj
,然后跟随并查找myString
,或者是否存在诸如全局地址表之类的内容,其中obj.myString
的地址为直接存储吗? -
obj
的参考值存储在哪里?它是program
对象块的一部分,例如myString
是obj
对象块的一部分吗?(假设obj
是在实例program
内部创建的)
每个类或结构实例都有一个"个人内存空间";用于数据,但是所有对象共享一次方法.
首先,在x32上需要4个字节,在x64上需要8个字节来存储对对象内存地址的引用(引用是一个隐藏的指针,忘记了对其进行管理).
接下来,该对象在此处具有两个数据成员:
- 一个占用4个字节的整数.
- 这里需要5个字符的一个字符串:5x2字节= 10字节.
因此,对于数据,对象在x32上需要18字节,在x64系统上需要22字节.
由于字符串对象的长度包含一个整数,因此其大小略多于此:x32上为22,x64上为26.
由于字符串是引用,我们需要再次添加4或8个字节=>26或34个字节.
由于字符串在类声明中具有其他静态字段和实例字段,例如第一个字符,因此所需的时间要多于此.
字节是内存的基本单位,它一次存储一个值,介于0到255(无符号)或-128到+127(有符号)之间.
数据表示教程 >
今天看到了这个草图(2021.01.28),我意识到这可能具有误导性,这就是为什么我写了"这不是很真实的事实,但可能有助于理解",因为实际上在启动过程并存储过程时,从二进制文件EXE和DLL加载方法的实现代码是数据段(如果自x32和保护模式以来未发生任何变化).方法的非虚拟表以及方法的虚拟表未存储在每个对象实例的数据段中.我不记得详细信息,但是这些表是用于代码的.同样,对象的每个实例的数据都是其定义及其祖先的投影,在一处是一个完整的实例.
I am wondering how the memory layout for this class (its object) would look like:
class MyClass
{
string myString;
int myInt;
public MyClass(string str, int i)
{
myString = str;
myInt = i;
}
}
MyClass obj = new MyClass("hello", 42);
Could anyone visualize that?
Update:
Based on the answer from Olivier Rogier and the comments from ckuri and Jon Skeet I tried to come up with a high level chart, heavily influenced by the devblog article mentioned by ckuri.
So to my understanding:
obj
(8 bytes reference) points to the object including metadata (actually not to its beginning, but let's ignore that for simplicity).At this place the
myInt
is stored and themyString
reference value (which is the reference to the real string value)
I don't want to got into the last details, but what I am still curious about:
If
obj.myString
shall be accessed, are there two "lookups" necessary, e.g. first looking upobj
, then following it and looking upmyString
or is there something like a global address table where the address forobj.myString
is directly stored?Where is the reference value of
obj
stored? Is it part of theprogram
object block likemyString
is part of theobj
object block? (assumingobj
is created inside an instanceprogram
)
Each instance of a class or struct has a "personal memory space" for data, but methods are shared once for all objects.
First, you need 4 bytes on x32 or 8 bytes on x64 to store the reference to the memory address of the object (reference is a hidden pointer to forget to manage it).
Next, the object has two data members here:
- One integer that takes 4 bytes.
- One string that here takes 5 chars : 5x2 bytes = 10 bytes.
So for data the object takes 18 bytes on x32 or 22 bytes on x64 system.
Since string object contains an integer for the length, the size is a little more than that : 22 on x32 and 26 on x64.
Since string is a reference, we need to add again 4 or 8 bytes => 26 or 34 bytes.
Since string has some other static and instance fields in the class declaration like the first char, it takes a little more than this.
Is string actually an array of chars or does it just have an indexer?
In addition to that, the memory in the code segment has the instructions of the code of methods. This code is common for all instances.
In addition to that, there are class tables and virtual tables to describe types, methods signatures and polymorphism rules.
If the object is instantiated in a method it uses the heap memory.
If the object is instantiated in the declaration as a class member, I don't know how works .NET but it may be allocated in the data segment of the processus.
And memory is like a train where wagoons are the bytes.
Here is a pseudo-diagram of the memory.
It is not the very true reality but it may help to understand:
Does accessing a variable in C# class reads the entire class from memory?
C# Heap(ing) Vs Stack(ing) In .NET
A byte is the elementary unit of the memory that stores one value at a time between 0 and 255 (unsigned) or -128 and +127 (signed).
Learn the basics about C# data types' variables
Shifting Behavior for Signed Integers
A Tutorial on Data Representation
Seeing this sketch today (2021.01.28) I realize it may be mlisleading, and it is why I wrote "It is not the very true reality but it may help to understand", because in reality the code of the implementation of methods are loaded from the binary files EXE and DLLs when the process is starded and is stored is the CODE SEGMENT, as all data, static (literals) and dynamic (instances) are in the DATA SEGMENT (if things had not changed since x32 and protected mode). Methods' non-virtual tables as well as methods' virtual tables are not stored in the data segment for each instance of objects. I don't remember details but these tables is for code. Also Data of each instance of an object is a projection from its definition as well as its ancestors, in one place, one full instance.
这篇关于该对象的内存看起来如何?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!