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

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

问题描述

我想知道此类(其对象)的内存布局如何:

  class MyClass{字符串myString;int myInt;公共MyClass(s​​tring str,int i){myString = str;myInt = i;}}MyClass obj = new MyClass("hello",42); 

有人可以想象吗?

更新:

基于奥利维尔·罗吉尔(Olivier Rogier)的回答以及ckuri和乔恩·斯凯特(Jon Skeet)的评论,我试图提出一个受

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

  1. 如果应访问 obj.myString ,是否需要两个查找",例如首先查找 obj ,然后跟随并查找 myString ,或者是否存在诸如全局地址表之类的内容,其中 obj.myString 的地址为直接存储吗?

  2. 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个字节.

由于字符串在类声明中具有其他静态字段和实例字段,例如第一个字符,因此所需的时间要多于此.

C#堆(ing)与.NET中的Stack(ing)

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

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

签名整数的转换行为

数据表示教程


今天看到了这个草图(2021.01.28),我意识到这可能具有误导性,这就是为什么我写了"这不是很真实的事实,但可能有助于理解",因为实际上在启动过程并存储过程时,从二进制文件EXE和DLL加载方法的实现代码是内存分段

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天全站免登陆