变量如何处理RAM?

Fra*_*kie 2 c# computer-science

我对此很陌生,所以如果问题没有意义,我会提前道歉.

如果我是正确的,c#中的int是4个字节.如果我有声明:

int x;
Run Code Online (Sandbox Code Playgroud)

我认为这占用了4个字节的内存.如果每个存储器地址空间是1个字节,那么这将占用四个地址槽?如果是这样,x如何映射到四个地址位置?

Eri*_*ert 11

如果我有声明,int x;我会认为这占用了4个字节的内存.x如何映射到四个字节的地址?

首先,迈克是正确的.C#专门设计,因此您无需担心这些问题.让内存管理员为您处理; 它做得很好.

假设您确实希望看到香肠是如何制作的,以供您自己的启发:您的假设是不合理的.这种说法并不需要引起任何的内存消耗.如果它确实导致消耗内存,则int消耗四个字节的内存.

局部变量(*)有两种方式可以不占用内存.首先是它从未使用过:

void M()
{
    int x;
}
Run Code Online (Sandbox Code Playgroud)

编译器可以足够聪明地知道x永远不会被写入或读取,并且它可以完全合法地省略.显然,它不会占用任何记忆.

第二种不占用内存的方法是抖动选择注册本地.它可以专门为该局部变量分配一个机器寄存器.然后该变量没有与之关联的地址,因为显然寄存器没有地址.(**)

假设本地确实占用内存,则抖动负责跟踪该内存的位置.

如果本地是一个完全正常的局部,那么抖动会使堆栈指针碰到四个字节,从而在堆栈上保留四个字节.然后它将这四个字节与本地相关联.

如果本地是匿名函数的本地外部本地,迭代器块的本地或异步方法的本地,则C#编译器将生成本地作为类的字段; 抖动要求垃圾收集器分配类实例,抖动将本地与垃圾收集器与该实例关联的内存缓冲区的开头的特定偏移量相关联.

所有这些都是实施细节,随时可能发生变化; 不要依赖它.

(*)我们知道它是一个局部变量,因为你说它是一个声明.字段声明不是声明.

(**)如果不安全代码采用本地地址,显然无法注册.


riw*_*alk 5

可以说有很多(我的意思是很多).您正在遇到的各种主题包括堆栈,符号表,内存管理,内存层次结构 ......我可以继续.

但是,既然你是新人,我会尝试给出一个更简单的答案:

在程序(例如int)中创建变量时,您告诉编译器在内存中为该数据保留空间.int是4个字节,因此保留4 个连续字节.您所指的内存位置仅指向开头.之后知道长度是4个字节.

现在,内存位置(在您提供的情况下)实际上并没有以与变量相同的方式保存.每次有需要x的命令时,该命令将替换为显式获取该内存位置的命令.换句话说,地址保存在程序的"代码"部分,而不是"数据"部分.

这仅仅是一个真的,真的高概述.希望它有所帮助.