这个对象的内存看起来如何? [英] How would the memory look like for this object?

查看:19
本文介绍了这个对象的内存看起来如何?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道这个类(它的对象)的内存布局是怎样的:

class MyClass{字符串 myString;int myInt;公共 MyClass(string str, int i){myString = str;myInt = i;}}MyClass obj = new MyClass("你好", 42);

谁能想象一下?

更新:

根据 Olivier Rogier 的回答以及 ckuri 和 Jon Skeet 的评论,我试图想出一个高级图表,深受

我不想进入最后的细节,但我仍然好奇的是:

  1. 如果要访问 obj.myString,是否需要两次查找",例如首先查找 obj,然后按照它查找 myString 或者是否有类似全局地址表的东西,其中 obj.myString 的地址是直接存储?

  2. obj 的引用值存放在哪里?它是 program 对象块的一部分,如 myStringobj 对象块的一部分吗?(假设 obj 是在实例 program 中创建的)

解决方案

类或结构的每个实例都有一个个人内存空间";数据,但所有对象共享一次方法.

首先,x32 上需要 4 个字节或 x64 上的 8 个字节来存储对对象内存地址的引用(引用是一个隐藏的指针,忘记管理它).

接下来,对象在这里有两个数据成员:

  • 一个需要 4 个字节的整数.
  • 这里有一个需要 5 个字符的字符串:5x2 字节 = 10 字节.

因此对于数据,对象在 x32 上占用 18 个字节或在 x64 系统上占用 22 个字节.

由于字符串对象包含一个整数作为长度,所以大小比这个多一点:x32 上为 22,x64 上为 26.

由于string是引用,我们需要再添加4或8个字节=>26 或 34 字节.

由于字符串在类声明中还有一些其他的静态和实例字段,比如第一个字符,所以需要多一点.

访问 C# 类中的变量是否会从内存中读取整个类?

C# 堆(ing) Vs Stack(ing) 在 .NET 中

字节是内存的基本单位,它一次存储 0 到 255(无符号)或 -128 到 +127(有符号)之间的一个值.

了解有关 C# 数据的基础知识类型变量

有符号整数的转移行为

数据表示教程


今天(2021.01.28)看到这个草图,我意识到它可能具有误导性,这就是为什么我写了这不是非常真实的现实,但它可能有助于理解",因为实际上,当进程启动并存储时,方法实现的代码是从二进制文件 EXE 和 DLL 中加载的 代码段,因为所有数据、静态(文字)和动态(实例)都在 DATA SEGMENT(如果自 x32 和保护模式以来事情没有改变).方法的非虚拟表和方法的虚拟表不存储在每个对象实例的数据段中.我不记得细节,但这些表是用于代码的.此外,对象的每个实例的数据都是其定义及其祖先的投影,在一个地方,一个完整的实例.

内存分割

x86 内存分段

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:

  1. obj (8 bytes reference) points to the object including metadata (actually not to its beginning, but let's ignore that for simplicity).

  2. At this place the myInt is stored and the myString 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:

  1. If obj.myString shall be accessed, are there two "lookups" necessary, e.g. first looking up obj, then following it and looking up myString or is there something like a global address table where the address for obj.myString is directly stored?

  2. Where is the reference value of obj stored? Is it part of the program object block like myString is part of the obj object block? (assuming obj is created inside an instance program)

解决方案

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.

Memory segmentation

x86 memory segmentation

这篇关于这个对象的内存看起来如何?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆