园子里几位大师的文章,已经认真拜读过,但感觉自己产生了误解,还请多多指教:
参考文章:
1.http://www.cnblogs.com/artech/archive/2010/10/20/CLR_Memory_Mgt_02.html对于字符串类型的strInstance,由于《上篇》所讲述的关于字符串驻留机制,最后总的字符串被分配到系统程序域中... 2.http://www.cnblogs.com/artech/archive/2007/05/06/737130.html而对于一个string来说,它始终被interning table引用,而这个interning table是针对一个Process的,是被该Process所有AppDomain共享的,所以一个string的生命周期相对比较长,只有所有的AppDomain都不具有对该string的引用时,他才有可能被垃圾回收。
疑惑:
问题一:”驻留字符串是保存在系统程序域,以中立域方式记录在哈希表中“。
疑惑:1.哈希表的键是字符串的值,还是字符串的哈希值?
2.哈希表的值,指向的字符串是存储在默认程序域的托管堆中,还是系统程序域中?
问题二:“动态生成的字符串”。
疑惑:1.若没有强制启用驻留,则是分配在托管堆中,还是系统程序域中?
2.若调用string.Intern方法强制驻留,则在动态生成的过程中产生了中间字符串,再根据中间字符串的值在驻留池中查找并返回引用,这样的话中间字符串不是浪费了内存?
解决措施:
昨天刚注册还不能发提问,所以恳请百度知道团队给出的解答,和我的理解基本一致:http://zhidao.baidu.com/question/540933704?quesup2&oldq=1
为了验证字符串是存储在托管堆中,写个小程序在本机打印出内存地址:
string str1 = "a"; List<double> list44 = new List<double>() { 21 }; string str2 = "b"; string str3 = "ab"; string str4 = "a" + "b"; List<double> list = new List<double>() { 21}; Person p = new Person(20); string str5 = str1 + str2; string str6 = string.Intern(str1 + str2); string str7 = new string(new char[] { 'a', 'b' }); string str8=string.Intern(new string(new char[] { 'a', 'c' })); string str9 = new string(new char[] { 'a', 'c' }); List<double> list2 = new List<double>(); |
0x02329950 0x02329a44 0x02329964 0x02329978 0x02329978 0x02329aac 0x02329afc 0x02329b08 0x02329978 0x02329b48 0x02329b70 0x02329b98 0x02329bb0 |
结论一:在编译、生成元数据的过程中,操作字符串常量默认启用驻留机制。
结论二:不管是驻留字符串,还是动态生成的非驻留字符串,都是在托管堆中存储。
结论三:系统程序域中的驻留池维护的哈希表,保持了对驻留字符串的引用,使其不被回收且在同一进程中共享。
结论四(猜想):驻留池中的哈希表的键,应该不是字符串的值,而是字符串的哈希值。
初次发文,请园友们多多指导!