我对C#中只有引用类型被垃圾收集的事实感到有点困惑。 这意味着GC仅挑选存储器取消分配的参考类型。 那么值类型会发生什么,因为它们也会占用堆栈中的内存?在C#中销毁结构对象?
回答
一开始,无论他们是堆的堆或部分依赖于什么情况下他们的一部分 - 如果他们是引用类型之内,他们将在堆上反正。 (你应该考虑多少你真的关心栈/堆鸿沟无论如何 - 作为埃里克利珀写,这是largely an implementation detail)
然而,当上下文被收回基本值类型的内存被回收 - 所以即使堆栈你从方法返回时弹出,“回收”整个堆栈帧。同样,如果值类型值实际上是对象的一部分,那么当对象被垃圾收集时,内存将被回收。
简短的回答是,你不必担心它:)(这里假设你没有任何东西其他比内存担心,当然 - 如果你已经有了引用的结构对需要释放原生手柄,这是一个有些不同的情景。)当堆栈帧被删除,已执行后,我会承担
堆栈中的值类型超出范围时将从堆栈中删除。
值类型一旦超出范围就会被销毁。
值类型将得到释放
还要补充一点,堆在一个线程级别,并且堆在应用程序域级别。
所以,当一个线程结束,将通过RECLAM特定线程使用的堆栈存储器。
有在这个问题上使用,比如破碎,回收,重新分配,除去过多的动词。这与实际发生的情况并不相符。局部变量根本不复存在,Norwegian parrot style。
的方法,具有一个入口点,即首先发生的事情是,CPU堆栈指针调整。创建一个“堆栈框架”,即本地变量的存储空间。 CLR保证这个空间被初始化为0,而不是因为明确的分配规则而在C#中强烈使用的功能。
的方法有出口的一个点,即使你方法的代码穿插着多个return
语句。此时,堆栈指针会简单地恢复到其原始值。实际上,它“忘记”那里的局部变量。它们的值不以任何方式“擦除”,字节仍然存在。但是它们不会持续很长时间,您的程序中的下一次呼叫将会再次覆盖它们。 CLR零初始化规则确保您永远不会观察那些不安全的旧值。
非常非常快,只需要一个处理器周期。这种行为在C#语言中的可见副作用是值类型不能有终结器。确保不需要做额外的工作。
这个局部变量已经不存在了!它已不复存在!这是一个前变量。 :) – 2015-12-05 08:03:08
我对C#中只有引用类型被垃圾收集的事实感到困惑。
这不是事实。或者说,这个陈述的真实性或虚假性取决于你的意思是“收集垃圾”。垃圾收集器在收集时肯定会查看值类型;这些值类型可能还活着,并持有到引用类型:
struct S { public string str; }
...
S s = default(S); // local variable of value type
s.str = M();
在垃圾收集器运行时,它看起来确实在s,因为它需要确定s.str还活着。
我的建议:澄清精确地您的动词“获取垃圾收集”意味着什么。
GC仅挑选存储器取消分配的参考类型。
同样,这不是事实。假设有的
class C { int x; }
为整数存储器中的实例将是对垃圾收集堆,并且因此被垃圾收集器回收时C的实例变为无根。
为什么你认为只有引用类型的内存被垃圾收集器释放的假?正确的说法是被垃圾回收器分配为的内存是,垃圾回收器取消分配了,我认为这很有道理。 GC分配它,所以它负责清理它。
那么值类型会发生什么,因为它们也会占用堆栈中的内存?
没有什么事情发生在他们身上。没有什么需要发生在他们身上。该堆栈是一百万字节。线程启动时确定栈的大小;它始于一百万字节,并且在整个线程执行期间它保持一百万字节。堆栈中的内存既不被创建也不被破坏;只有其内容被改变。
“堆栈中的内存既不被创建也不被破坏” - 我建议我们称之为** Lippert内存保存法则**。 :) – 2010-01-27 19:11:26
.NET中的每个值类型实例都是其他内容的一部分,可能是更大的封闭值类型实例,堆对象或堆栈帧。每当这些事情产生时,其中的任何结构也会产生;那么只要包含它们的东西确实存在,那些结构就会继续存在。当包含结构的东西不复存在时,结构也会如此。在没有破坏容器的情况下,没有办法摧毁一个结构,并且无法销毁包含一个或多个结构的东西而不破坏其中包含的结构。
- 1. 在X ++中销毁对象
- 2. 如何销毁C#中的COM对象?
- 3. 销毁C中的非托管对象#
- 4. 部分构建和销毁层次结构中的儿童课程对象
- 5. Python:全局对象销毁
- 6. 销毁主类对象
- 7. 如何销毁java对象?
- 8. 如何销毁PDFJS对象?
- 9. 销毁Oracle PLSQL对象
- 10. 销毁对象的错误
- 11. 如何在C中销毁一个对象#
- 12. Unity2d - 销毁对象使用销毁(gameObject)//它会销毁与脚本连接的对象
- 13. C#通过Excel过程销毁多个Excel对象的正确方法销毁
- 14. 摧毁主要对象时销毁嵌入对象
- 15. Ruby中对象销毁的通知
- 16. 父母被销毁时如何销毁子对象?
- 17. 在添加新对象时销毁向量中的对象
- 18. C++类的成员对象:它应该在哪里被销毁?
- 19. 销毁由脚本Unity3d C#中的脚本创建的对象#
- 20. 在所述对象调用的事件期间销毁对象
- 21. 使用javascript销毁闪存对象
- 22. 销毁其他人参考的对象
- 23. php新手问题:销毁类对象?
- 24. 重置/销毁对象实例
- 25. 耙耙销毁Rails 3对象?
- 26. 统一对象已被销毁
- 27. 销毁对象,而它的ID
- 28. 试图访问被销毁对象
- 29. 从JRuby销毁Java类的对象
- 30. 使用javascript销毁嵌入对象
感谢您参考此综合性文章。我发现Eric Lippert的全局指令与整个c#哲学非常一致:“只关注语义,我们会为你处理其余的问题” – 2013-12-10 15:32:34