堆栈和堆内存效应?
在下面的代码中:
MyClass oMyClass1;
MyClass oMyClass2 = null;
我的疑问是上面两行将如何影响内存(堆栈和堆)。
会在堆栈中创建引用吗?
In the following code:
MyClass oMyClass1;
MyClass oMyClass2 = null;
My doubt is how the above two lines will affect memory (stack & heap).
Will create reference in stack?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
信息不足,有 2 种可能性:
它们是局部变量。在这种情况下,这两行在堆栈上进行 2 个相同的分配(引用,始终为 32/64 位)(无论何时执行方法以及执行多长时间)。堆上没有分配。
它们是类或结构中的字段。在这种情况下,这两行在创建实例时分别分配实例中引用的大小。该实例可以分配在堆栈上(当它们是结构成员时)或堆上(类成员)。
Insufficient information, 2 possibilities:
they are local variables. In that case those 2 lines make 2 identical allocations (of a reference, always 32/64 bits) on the stack (whenever and for how long the method is executed). No allocations on the heap.
they are fields in a class or struct. In that case those 2 lines each allocate the size of a reference in the instance when it is created. That instance could be allocated on the stack (when they are struct members) or on the heap (class members).
严格来说,这取决于代码在哪里。
如果代码位于常规函数/方法中,它将仅影响堆栈。这不会对堆产生任何影响,因为尚未构造任何 MyClass 对象。
假设 MyClass 是一个类(即引用类型),每个声明都将在堆栈上保留足够的空间来保存对 MyClass 对象的引用。
这两个声明略有不同 - 第一个声明尚未初始化,因此在将 oMyClass1 设置为某项之前尝试访问 oMyClass1 将给出编译器错误。第二个已初始化,因此您不会收到编译器错误[尽管如果您在将 oMyClass2 设置为引用实际对象之前访问它的方法或属性,例如使用 oMyClass2 = new MyClass() ,则会收到运行时错误;]。
如果代码位于类声明内:
那么它只会在 Fred 构造函数期间执行。在调用构造函数之前,空间(对于 Fred 对象,包括两个 MyClass 引用的空间)已经在堆上分配。这两行代码实际上没有任何效果,因为空间已经被初始化为空。
如果它位于结构声明内部,则效果将类似,仅在堆栈(如果结构是本地的)或全局变量内存(如果结构是静态的)上。 [尽管,公平地说,我有点不确定 C# 中静态分配的位置 - 我只是假设它的完成方式与 C++ 类似]
Strictly speaking, it depends on where the code is.
If the code is in a regular function/method, it will affect the stack only. There will be no effect on the heap, because no MyClass objects have been constructed yet.
Assuming MyClass is a class (i.e. reference type), the declarations will each reserve enough space on the stack to hold a reference to a MyClass object.
The two declarations are slightly different - the first one has not been initialised, so any attempt to access oMyClass1 before it is set to something will give a compiler error. The second one is initialised, so you will not get a compiler error [although you will get a runtime error if you access a method or property of oMyClass2 before you set it to refer to an actual object, e.g. with oMyClass2 = new MyClass();].
If the code is inside a class declaration:
then it will only be executed during the Fred constructor. The space (for a Fred object, including space for two MyClass references) will already have been allocated on the heap before the constructor is called. The two lines of code will actually have no effect, as the space will already have been initialised to null.
If it is inside a struct declaration, the effect will be similar, only on the stack (if the struct is local) or global variable memory (if the struct is static). [Although, to be fair, I'm a tiny bit unsure where statics get allocated in C# - I am just assuming it is done in a similar way to C++]