【问题标题】:.net Garbage Collection and managed resources.net 垃圾收集和托管资源
【发布时间】:2010-10-04 08:24:47
【问题描述】:

原始数据类型(int、char 等)的内存是在离开作用域后立即释放,还是添加到垃圾回收中以供以后释放?

考虑:

For x as integer=0 to 1000
dim y as integer
Next

如果这没有将 1000 个整数添加到垃圾收集器以供以后清理, 它如何处理字符串对象?这会创建 1000 个字符串以便稍后清理吗?

For x as integer=0 to 1000
dim y as string=""
Next

只包含 int、string 等数据类型的结构怎么样?

只包含托管资源的类?

【问题讨论】:

    标签: .net memory-management memory-leaks garbage-collection performance


    【解决方案1】:

    原始数据类型(字符串除外)是值类型,是在堆栈而不是堆上创建的。当它们超出范围时,它们会从堆栈中弹出;它们不是垃圾收集的。

    字符串是引用类型,在堆上分配,并被垃圾回收。 .NET 使用String Interning 对字符串的内存管理进行了一些优化。 (也就是说,你可能在内存中只有一个字符串 "" 的实例。.NET 可以做到这一点,因为字符串是不可变的)

    【讨论】:

      【解决方案2】:

      好的,只有两个答案已经有错误信息了......

      • 字符串不是原始类型
      • 字符串不是值类型
      • 值类型值并不总是在堆栈上创建 - 这取决于变量的位置。如果它是类的一部分,则它与该对象的其余数据一起存储在堆中。
      • 即使 局部 变量被捕获(例如在匿名函数和迭代器块中),它们也可能最终出现在堆中
      • 诸如“”之类的字符串文字是interned - 它们总是解析为相同的字符串。该循环实际上并没有创建任何字符串。

      有关详细信息,请参阅我在 what goes where in .NET memory 上的文章。您可能还想考虑whether it's important or not

      【讨论】:

      • 不,不是:msdn.microsoft.com/en-us/library/system.type.isprimitive.aspx "原始类型是 Boolean、Byte、SByte、Int16、UInt16、Int32、UInt32、Int64、UInt64、IntPtr、UIntPtr、Char、Double 和 Single。"我相信 VB 规范 :)
      • 并且 typeof(string).IsPrimitive 肯定返回 false。 C# 规范只使用了两次“原始”一词,并且在这两种情况下都没有定义该术语。 ECMA-335 没有定义它,但分区 III 的第 1.8.1.1 节提到了对原始类型值进行装箱,这不适用于字符串。
      • 再一次,你说得对,我很快就说了两句,而且说得太笼统了。我知道我的意思,但没有很好地传达它。好答案(再次):)
      • 那么对于 vb.net windows 应用程序,由于所有代码都在一个对象上,它很可能都在堆上,创建一个保存数据的对象的效率与一个保存相同的结构根本不重要?除了传递结构 byVal 而没有获取数据的机会吗?
      • 没有。并非所有内容都在对象中(无论如何,通过“对象”的 C# 定义 - 类的实例,包括用于装箱值类型的类型)。并非所有内容都在堆上 - 阅读链接。值类型的局部变量通常将其数据存储在堆栈中。 (续)
      【解决方案3】:

      已经给出了两个答案,除了this article 之外我没有什么可以补充的了,它很好地描述了垃圾收集在 .Net 中的工作原理。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多