0

当我声明变量然后为该变量创建对象时,后台会发生什么(在内存的情况下)。引用变量是否存储在任何地方,以何种格式存储,以及该变量如何指向堆上的内存。请在评论中澄清以下疑问。

例如

ClassA instance;       // Where this variable store and how much memory occupies
instance=new ClassA(); //How instance variable points to memory

编辑

如果我的程序包含这么多未使用的变量,会对我的程序内存产生什么影响。

4

4 回答 4

1

引用本身的局部变量的存储位置取决于平台(抖动可以选择他们想要存储它的位置。)通常它将在定义本地方法的调用堆栈的内存中或在 CPU 寄存器中。大小也取决于平台,但对于 32 位架构,通常为 4 字节,对于 64 位架构,通常为 8 字节。

引用可能会或可能不会“指向”堆。最好将其视为可用于访问对象的不透明引用标识符。底层指针可以在运行时更改。

对于未使用的变量,优化编译器通常会完全消除任何未使用的局部变量,因此它对运行时性能完全没有影响。此外,您所说的用于存储引用的开销类型对于现代平台来说是微不足道的。

于 2012-11-18T17:13:22.887 回答
1

引用变量是内联存储的。如果是局部变量,则分配在堆栈上,如果是类的成员,则分配为堆上对象的一部分。

一个类的实例总是在堆上分配。

引用只是一个指针,但特别是垃圾收集器知道引用。因此,引用使用指针使用的空间量。在 32 位进程中它使用 4 个字节,在 64 位进程中它使用 8 个字节。

于 2012-11-18T17:16:36.563 回答
1

实例变量在运行时只是一个指针,它指向在 GC 堆中分配的对象。该变量可以存在于任何位置,堆栈、CPU 寄存器、堆上的另一个对象或加载器堆中的另一个对象(如果它是静态的)。

垃圾收集器最重要的是它能够在垃圾收集期间找到这个指针。因此可以看到该对象仍然被引用,并且可以在压缩堆时调整指针值。当引用在另一个对象内部是静态的时,这相当简单。当它在堆栈或寄存器上时更难,抖动提供了足够的信息让 GC 找到它。

于 2012-11-18T17:16:48.043 回答
0

如果您需要有关此问题的答案,那么我建议您了解“通过 C# 进行 CLR”,这是一本关于 CLR 如何工作的书,其中包含大量有关此的信息。

要回答您的问题,您需要考虑很多事情来回答这个问题。

例如,您需要将每个方法的指令存储在类中。当类第一次加载时,这实际上是一个指向 .Net IL 指令的指针。当应用程序第一次需要该方法时,它将被 JIT 编译为处理器的实际指令,并将其存储在内存中。

然后你有类字段的静态存储,每个类只存储一次。

.Net 中实例化的每个类都需要存储,原因有很多,但不限于继承、垃圾收集、布局等。然后,您可以存储各种引用,这些引用可能会保留给本身将存储的对象。

如果内存对您正在做的事情真的很重要,那么 C# 可能不是您的应用程序的最佳选择。否则,只需享受使用 .NET 所带来的生产力优势,并接受这种易用性伴随着内存使用的代价和 C/C++ 应用程序的较低性能(在某些情况下)。

于 2012-11-18T17:17:34.317 回答