我听到了关于这个话题的不同说法,现在想寻求一些清晰明确的答案。
如何立即丢弃一个string
对象,或者至少清除它的痕迹?
我听到了关于这个话题的不同说法,现在想寻求一些清晰明确的答案。
如何立即丢弃一个string
对象,或者至少清除它的痕迹?
这取决于字符串类型。默认情况下,文本字符串被池化 (interned),因此即使您的应用程序不再引用它,它也不会被垃圾回收,因为它由内部的池化结构引用。其他字符串就像任何其他托管对象一样。一旦应用程序不再引用它们,它们就有资格进行垃圾回收。
关于池化的更多信息,请参见此问题:Java和.NET字符串字面值位于哪里?
string s = "hello";
它将被内部化,而在运行时创建的任何字符串都不会被内部化,除非您自己这样做。 - Brian Rasmussenpublic unsafe static void Clear(this string s)
{
fixed(char* ptr = s)
{
for(int i = 0; i < s.Length; i++)
{
ptr[i] = '\0';
}
}
}
GC.Collect()
强制运行清理。从文档中可以看到:
这应该是最接近的翻译了!使用此方法尝试回收所有不可访问的内存。
所有对象,无论它们在内存中存在多长时间,都将被考虑进行收集;但是,在托管代码中引用的对象不会被收集。使用此方法强制系统尝试回收最大量的可用内存。
没有确定的方法可以清除内存中字符串(System.String
)的所有痕迹。您唯一的选择是使用SecureString
对象。
限制内存中字符串对象的生命周期的最佳方法之一是将它们声明为尽可能内层作用域的本地变量,而不是在类上声明为私有成员变量。
初级开发人员常见的错误是在类本身上将他们的字符串声明为'private string ...
'。
我也看到过有好心的有经验的开发人员试图在私有成员变量中缓存一些复杂的字符串连接(a+b+c+d...),以便他们不必一直重新计算。大错特错——重新计算几乎不需要时间,在第一代GC发生时临时字符串会立即被垃圾收集,而缓存所有这些字符串所占用的内存只是从更重要的项目(如缓存的数据库记录或缓存的页面输出)中占用可用内存。
一旦不再需要字符串变量,请将其设置为null。
string s = "dispose me!";
...
...
s = null;
然后调用 GC.Collect()
来请求垃圾回收器,但是 GC 无法保证字符串会立即被回收。
dispose me!
是汇编代码中的文字,它将被内部化并永远不会被垃圾回收。然而就运行时构建的字符串而言,你是正确的。 - itowlson