2013-04-26 126 views
9

我的理解(这可能是错误的)是在c#中,当你创建一个字符串时,它会被变成“intern pool”。这保留了对字符串的引用,以便多个相同的字符串可以共享操作内存。如何防止字符串被拦截

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

+0

什么是你的希望做的比默认的行为以外的其他动机是什么? – 2013-04-26 09:45:57

+1

只要让GC做好工作。 – ken2k 2013-04-26 09:46:17

+6

不是每个字符串被拘留,[唯一的文字字符串(http://stackoverflow.com/questions/8509035/why-only-literal-strings-saved-in-the-intern-pool-by-default)。 – 2013-04-26 09:46:46

回答

4

如果您出于安全原因需要从内存中移除字符串,请使用SecureString。否则,如果在任何地方没有对字符串的引用,则GC将无论如何都将其清除(它将不再被实施),因此您不必担心实习。

当然,只有字符串文字被放在第一位(或者如上面Petr和其他人所说的那样调用String.Intern())。

+5

@downvoter:你能解释一下为什么,只是为了帮助阅读这个答案的其他人? – 2013-04-26 09:52:46

+1

SecureString不是一个解决方案。这听起来很“安全”,但如果我正确地阅读他的问题,他不需要从内存中删除它们,因为他害怕黑客或其他东西。他只是想要回忆他的工作记忆。 – 2013-04-26 10:13:23

+0

@MartinMulder这个问题并不完全清楚,因此在我的答案的第一行中使用了术语“* if *”。 – 2013-04-26 10:17:40

5

应用CompilationRelaxations属性来将整个组件(看起来像的唯一可能的解决方案是禁止实习在组装电平)如下:

[assembly: CompilationRelaxations(CompilationRelaxations.NoStringInterning)] 

更多信息CompilationRelaxations

UPDATE:

该文档指出属性:

将程序集标记为不需要字符串文字实习

换句话说,它不妨碍编译器进行字符串 实习,只是提供一个暗示它不是必需的。 文档在这方面有点稀疏,但是这似乎也是this MSDN forum post中的结论 。

this SO question该属性

+5

这将有助于了解downvote的原因 – 2013-04-26 09:53:36

+1

将程序集标记为**,不需要**字符串文字实习,这与将该功能关闭为http://social.msdn.microsoft不同。 com /论坛/ zh-CN/clr /线程/ c1c1d969-8d6b-4aaf-b7f4-3febedf3cd18/ – 2013-04-26 09:58:34

+0

@TimSchmelter更新答案与链接+解释从相关的SO问题和提到的MSDN线程。谢谢 – 2013-04-26 10:03:21

1

尝试阻止实习我会建议使用String.IsInterned()找出之前无论您是关注实际上在实习的所有字符串。如果该函数返回null,则您的字符串不会被禁用。

据我所知,在运行时动态生成的字符串根本就没有被执行,因为没有任何性能优势。

1

你说的事情:

  • 你正在处理大量的字符串,那么你所谈论的运行值。
  • 想要在完成处理后从内存中删除字符串。

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

运行字符串由GC自动删除,如果没有给他们任何引用。实习生会有更多的参考资料,但在您的过程结束时,我认为所有参考资料都会被删除。实习机制不保留硬参考,而是坚持参考。一个弱引用被GC忽略,所以字符串实例仍然可以被删除。请参阅:http://msdn.microsoft.com/en-us/library/system.weakreference.aspx

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