当我声明变量然后为该变量创建对象时,在后台(在内存的情况下)会发生什么。引用变量是否存储在任何位置以及格式以及此变量如何指向堆上的内存。请在评论中澄清以下疑问。
例如
ClassA instance; // Where this variable store and how much memory occupies
instance=new ClassA(); //How instance variable points to memory
修改
如果我的程序包含这么多未使用的变量,会对程序存储器产生什么影响。
答案 0 :(得分:1)
引用本地变量的存储位置本身是平台相关的(抖动可以选择它们想要存储它的位置。)通常,它将位于调用堆栈的内存中,用于定义本地或CPU寄存器的方法。大小也取决于平台,但对于32位体系结构通常为4个字节,对于64位体系结构通常为8个字节。
引用可能会也可能不会“指向”堆。最好将它视为可用于访问对象的不透明引用标识符。底层指针可以在运行时更改。
关于未使用的变量,优化编译器通常会完全消除任何未使用的局部变量,因此它对运行时性能完全没有影响。此外,您正在讨论的用于存储引用的开销类型对于现代平台来说是微不足道的。
答案 1 :(得分:1)
引用变量以内联方式存储。如果它是一个局部变量,它在堆栈上分配,如果它是一个类的成员,它被分配为堆上对象的一部分。
总是在堆上分配类的实例。
引用只是一个指针,但特别之处在于垃圾收集器知道引用。因此,引用使用指针使用的空间量。在32位进程中,它使用4个字节,在64位进程中,它使用8个字节。
答案 2 :(得分:1)
实例变量只是运行时的指针,它指向GC堆中分配的对象。变量可以存在于任何地方,堆栈,CPU寄存器,在堆上或加载器堆中的另一个对象内,如果它是静态的。
关于垃圾收集器的重要事项是它能够在垃圾收集期间找到这个指针。因此可以看到对象仍然被引用,并且可以在压缩堆时调整指针值。当引用在另一个对象内部是静态的时,这是相当直接的。当它在堆栈或寄存器上时更难,抖动提供足够的信息让GC找到它。
答案 3 :(得分:0)
如果您需要这方面的答案,那么我建议您开始使用“CLR via C#”,这是一本关于CLR如何运作的书,它包含了大量有关此内容的信息。
要回答您的问题,您需要考虑许多事情来回答这个问题。
例如,您需要在类中存储每个方法的指令。当类首次加载时,这将有效地成为指向.Net IL指令的指针。当应用程序首次需要该方法时,它将被JIT编译为处理器的实际指令,并将存储在内存中。
然后你有类字段的静态存储,每个类只存储一次。
.Net中实例化的每个类都需要存储,原因有多种,但不限于继承,垃圾收集,布局等。然后,您可以存储您可以保留到对象的各种引用,这些引用本身将用于存储。
如果内存对您正在做的事情至关重要,那么C#可能不是您应用程序的最佳选择。否则,只需享受使用.NET所带来的生产效率,并接受这种易用性带来的内存使用价格以及来自C / C ++应用程序的性能降低(在某些情况下)。