11

我的理解(可能是错误的)是,在 c# 中,当您创建一个字符串时,它会被实习到“实习池”中。这保留了对字符串的引用,以便多个相同的字符串可以共享操作内存。

但是,我正在处理很多很可能是唯一的字符串,一旦完成每个字符串,我需要将它们从操作内存中完全删除,并且我不确定如何删除缓存的引用,以便垃圾收集器可以从内存中删除所有字符串数据。我怎样才能防止字符串被困在这个缓存中,或者我怎样才能清除它/或从中删除一个字符串,以便它肯定会从操作内存中删除?

4

4 回答 4

7

如果出于安全原因需要从内存中删除字符串,请使用SecureString.

否则,如果在任何地方都没有对字符串的引用,GC 无论如何都会清理它(它将不再被实习)所以你不必担心实习。

当然,首先只有字符串文字会被实习(或者如果您调用 String.Intern() ,如 Petr 和其他人在上面提到的)。

于 2013-04-26T09:46:33.533 回答
5

CompilationRelaxations属性应用于整个程序集(看起来唯一可能的解决方案是禁止在程序集级别进行实习),如下所示:

[assembly: CompilationRelaxations(CompilationRelaxations.NoStringInterning)]

更多关于CompilationRelaxations的信息

更新:

该文档指出该属性:

将程序集标记为不需要 string-literal interning

换句话说,它不会阻止编译器进行字符串实习,只是提供一个不需要它的提示。这方面的文档有点稀疏,但这似乎也是这个 MSDN 论坛帖子中的结论。

从关于该属性的这个 SO question

于 2013-04-26T09:46:46.237 回答
2

你对事情说:

  • 您正在处理很多字符串,因此您正在谈论运行时值。
  • 您想在处理完字符串后从内存中删除它们。

默认情况下,运行时值不被保留。当您从文件中接收字符串或自己创建字符串时,它们都有一个单独的实例。您可以通过 String.Intern 实习他们。实习字符串需要更多时间,但消耗更少的内存。请参阅:http: //msdn.microsoft.com/en-us/library/system.string.intern.aspx

如果没有引用运行时字符串,GC 会自动删除它们。实习生会有更多的参考资料,但在您的流程结束时,我假设所有参考资料都已删除。interning-mechanism 不保留 HARD 引用,而是保留 WEAK 引用。GC 会忽略弱引用,因此仍然可以删除字符串实例。请参阅:http: //msdn.microsoft.com/en-us/library/system.weakreference.aspx

所以……总结一下。默认情况下,您的运行时字符串不会被实习。如果他们被拘留,他们仍然会在你的工作完成后被 GC 删除。

于 2013-04-26T10:10:45.873 回答
1

在尝试阻止实习之前,我建议使用String.IsInterned() 来确定您关心的字符串是否实际上是实习的。如果该函数返回 null,则您的字符串不会被实习。

据我所知,在运行时动态生成的字符串根本不会被实习,因为不会有性能优势。

于 2013-04-26T09:55:03.470 回答