昨天调试一段程序发现内存始终释放不掉,最后终于发现是对String 的错误使用造成,这促使我今天 又仔细研究了一下String类型,不研究不知道,一研究发现我过去对String 的很多认识都是错误的,感 觉这种错误认识还比较有典型性,于是写下此文和大家一起探讨。
1. String 类型变量追加,或修改后的新String对象是驻留(Interned)的。
如下面代码
string s1 = "abcd"; string s2 = s1 + "e";
我过去想当然的认为s2 是驻留的,但实际上并非如此,用 string.IsInterned 方法检测s2是非驻留 的。后来研究发现只有常量字符串才会默认驻留,其他的字符串变量哪怕是采用 new string 构造出来 的,默认都非驻留,除非用string.Intern 强行驻留。后面我将提到驻留对内存的影响,微软之所以不让 所有的字符串都驻留,我认为还是处于内存方面的考虑。
2. String 变量不再引用后CLR会通过GC自动释放其内存。
string s1 = "abcd"; s1 = null;
上面代码,我想当然的认为s1 = null 后已经不再对 "abcd" 这个字符串引用,如果没有其他引用指 向这个字符串,GC会释放"abcd"这块内存。实际结果却是否定的。因为s1 被赋予了一个常量,导致 "abcd"这个字符串是驻留的,驻留的字符串在进程结束之前无法被自动释放。更糟糕的是,我昨天调试的 那段程序里面大量的字符串变量被采用 string.Intern 强制驻留,这导致我把所有的托管对象都释放了 依然无法释放那部分大概30多M的内存。
遗憾的是微软的MSDN中文版中string.Intern 的帮助信息里面竟然漏掉了性能考谅(Performance consideration) 这一节,我估计大多数中国程序员包括我在内如果有中文的帮助是懒得去看英文的。很 遗憾微软中文的帮助不知道为什么把最重要的部分给漏了。下面是英文帮助中Performance consideration 一节。
Performance Considerations
If you are trying to reduce the total amount of memory your application allocates, keep in mind that interning a string has two unwanted side effects. First, the memory allocated for interned String objects is not likely be released until the common language runtime (CLR) terminates. The reason is that the CLR's reference to the interned String object can persist after your application, or even your application domain, terminates. Second, to intern a string, you must first create the string. The memory used by the String object must still be allocated, even though the memory will eventually be garbage collected.
The .NET Framework version 2.0 introduces the CompilationRelaxations..::.NoStringInterning enumeration member. The NoStringInterning member marks an assembly as not requiring string-literal interning. You can apply NoStringInterning to an assembly using the CompilationRelaxationsAttribute attribute. Also, when you use the Native Image Generator (Ngen.exe) to compile an assembly in advance of run time, strings are not interned across modules.
看了英文的帮助就知道Intern 后的字符串是无法释放的了。
以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索内存
, string
, 字符串
, 变量
, intern()
, The
, Ngen.exe
, 对象驻留
Android对象驻留
string创建了几个对象、string占几个字节、empty string什么错误、string几个字节、string类型占几个字节,以便于您获取更多的相关知识。