【问题标题】:String Constant Memory pool in C#C#中的字符串常量内存池
【发布时间】:2013-09-16 15:27:13
【问题描述】:

大家都知道.Net框架中String对象是直接存储在堆内存中的

我只是想了解 .Net 框架中是否为字符串保留了任何内存。在 java 中,有一个为字符串保留的内存,称为 SCMP(字符串常量内存池),其中字符串被初始化和垃圾收集,就像堆内存中的其他对象一样。

【问题讨论】:

  • 我认为 Java 有这样一个特性,因为在过去,我们的移动设备内存有限。现在我们不需要这样的功能。对于编译器和垃圾收集器来说,它要简单得多。

标签: c# string memory


【解决方案1】:

我认为 .Net 中没有类似的东西。

相反,我阅读了 this 及其有趣的字符串使用方式:

CLR 维护一个称为实习池的表,其中包含 程序中的文字字符串。这样可以确保重复使用 代码中相同的常量字符串将使用相同的字符串 参考。 System.String 类提供了一个 Intern 方法,该方法 确保字符串在实习池中并返回对 它。

也检查这个MSDN:-

我们已经看到了许多托管堆包含 相同的字符串重复了数千次。结果是一个大工作 设置字符串消耗大部分内存的位置。在这个 在这种情况下,通常最好使用 string interning.

【讨论】:

    【解决方案2】:

    .Net 框架将字符串存储在一个表中,Intern Pool。你可能会看到:

    String interning and String.Empty - Eric Lippert

    如果您在一个编译单元中有两个相同的字符串文字,那么 我们生成的代码确保只有一个字符串对象由 程序集中该文字的所有实例的 CLR。这 优化称为“字符串实习”。

    String Interning .Net framework

    公共语言运行时通过维护来节省字符串存储 一个表,称为实习池,其中包含对 以编程方式声明或创建的每个唯一文字字符串 你的程序。因此,文本字符串的实例具有 特定值在系统中只存在一次。

    【讨论】:

      【解决方案3】:

      在 .NET 中,文字字符串是“内部”的,因此每个文字字符串只有一个副本。

      http://msdn.microsoft.com/en-us/library/system.string.intern.aspx

      【讨论】:

      • 这个答案具有误导性。 Literal 字符串是实习的。动态构造的字符串作为普通对象在堆上分配,不一定是唯一的。快速示例:Object.ReferenceEquals("abc", "ABC".ToLowerInvariant()) 的计算结果为 false,因为只有第一个字符串被保留。
      • @Douglas - 无意误导。答案是每个 literal 字符串都有一个副本。引用的 MSDN 参考非常清楚地表明,程序构造的字符串不会被实习,除非您使用 String.Intern 方法明确强制它们被实习。
      • 另外,仅仅因为一个字符串被实习并不意味着字符串内存在一个单独分配的地方。没有理由它不能只在常规堆内存中。关键是编译器会跟踪所有这些字符串并确保对所有文字使用相同的引用,它们不需要位于单独的内存池中。
      • 这可能只是我的迂腐,但我说的是“误导”,因为您的答案的第一部分可能会被误解为暗示所有字符串都已被保留。
      • @Douglas - 已更正,谢谢。我的意思是 .NET 使用实习来防止文字重复。与代码一样,最好让别人校对。
      猜你喜欢
      • 1970-01-01
      • 2014-06-08
      • 2012-12-18
      • 1970-01-01
      • 2020-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多