旅游网站建设的概念,wordpress 写模版,开网店怎么推广运营,php怎么写购物网站商品显示页面走钢丝的人#xff0c;在刺激中体验快感。带着问题思考#xff0c;在问题上迸发火花。
或者给问题以答案#xff0c;或者给答案以问题#xff0c;你可能永远无法看清全部#xff0c;但是总能从一点突破很多。事实的关键就在于面对问题#xff0c;我该如何思考#xff1…走钢丝的人在刺激中体验快感。带着问题思考在问题上迸发火花。
或者给问题以答案或者给答案以问题你可能永远无法看清全部但是总能从一点突破很多。事实的关键就在于面对问题我该如何思考
String Interning字符串驻留就是这样一个值得思考的话题带着问题思考我们至少要理清以下几个问题
什么是string什么是字符串驻留字符串驻留的运行机制及执行过程字符串驻留的其他问题
带着几个问号你必须知道的.NET继续更多体验。
1 带着问题
带着问题思考是技术探索的最佳实践 每当我收到很多朋友来函探讨技术的问题总能给我很多的技术思索和惊喜今天我们的话题就是由一个朋友的来函开始的你可以通过链接打开KiMoGiGi在To 王涛 的问题一文中精彩绝伦的思考和探讨带着他的提问引着我的思考完成本文对string的一点点探讨。 快捷参考 KiMoGiGi《To 王涛 的问题》 www.anytao.com 首先本文也无一例外的从8个测试开始也希望读者能沿着这几个简单的示例来思考答案。如果对此包含热情不妨可以试试你开始了吗 span stylecolor:blackspan stylecolor:black span stylecolor:#008000// Release : code01, 2008/08/20 /span/span/span // Author : Anytao, http://www.anytao.com span stylecolor:blackspan stylecolor:black span stylecolor:#0000ffstatic/span span stylecolor:#0000ffvoid/span Main() /span/span { span stylecolor:blackspan stylecolor:black span stylecolor:#0000ffstring/span s1 span stylecolor:#006080abc/span; /span/span Console.WriteLine(string.IsInterned(s1) ?? null); span stylecolor:blackspan stylecolor:black }/span/span 这是个简单的例题可以很快给出答案。 span stylecolor:blackspan stylecolor:black span stylecolor:#008000// Release : code02, 2008/08/20 /span/span/span // Author : Anytao, http://www.anytao.com span stylecolor:blackspan stylecolor:black span stylecolor:#0000ffstatic/span span stylecolor:#0000ffvoid/span Main() /span/span { span stylecolor:blackspan stylecolor:black span stylecolor:#0000ffstring/span s1 span stylecolor:#006080ab/span; /span/span s1 c; span stylecolor:blackspan stylecolor:black Console.WriteLine(span stylecolor:#0000ffstring/span.IsInterned(s1) ?? span stylecolor:#006080null/span); /span/span } 稍加修改这回的答案又该如何分析我们继续。 span stylecolor:blackspan stylecolor:black span stylecolor:#008000// Release : code03, 2008/08/20 /span/span/span // Author : Anytao, http://www.anytao.com span stylecolor:blackspan stylecolor:black span stylecolor:#0000ffstatic/span span stylecolor:#0000ffvoid/span Main() /span/span { span stylecolor:blackspan stylecolor:black span stylecolor:#0000ffstring/span s1 span stylecolor:#006080abc/span; /span/span string s2 ab; span stylecolor:blackspan stylecolor:black s2 span stylecolor:#006080c/span; /span/span span stylecolor:blackspan stylecolor:black span stylecolor:#0000ffstring/span s3 span stylecolor:#006080ab/span; /span/span span stylecolor:blackspan stylecolor:black Console.WriteLine(span stylecolor:#0000ffstring/span.IsInterned(s1) ?? span stylecolor:#006080null/span); /span/span Console.WriteLine(string.IsInterned(s2) ?? null); span stylecolor:blackspan stylecolor:black /span/span Console.WriteLine(string.IsInterned(s3) ?? null); span stylecolor:blackspan stylecolor:black }/span/span 如果上述执行过程你能很快给出答案那么恭喜了第一关看来不是那么费劲我们接着思考继续第二关 span stylecolor:blackspan stylecolor:black span stylecolor:#008000// Release : code04, 2008/08/20 /span/span/span // Author : Anytao, http://www.anytao.com span stylecolor:blackspan stylecolor:black span stylecolor:#0000ffstatic/span span stylecolor:#0000ffvoid/span Main() /span/span { span stylecolor:blackspan stylecolor:black span stylecolor:#0000ffstring/span s1 span stylecolor:#006080abc/span; /span/span string s2 ab; span stylecolor:blackspan stylecolor:black span stylecolor:#0000ffstring/span s3 s2 span stylecolor:#006080c/span; /span/span span stylecolor:blackspan stylecolor:black Console.WriteLine(span stylecolor:#0000ffstring/span.IsInterned(s3) ?? span stylecolor:#006080null/span); /span/span } 还有一个我们继续 span stylecolor:blackspan stylecolor:black span stylecolor:#008000// Release : code05, 2008/08/20 /span/span/span // Author : Anytao, http://www.anytao.com span stylecolor:blackspan stylecolor:black span stylecolor:#0000ffstatic/span span stylecolor:#0000ffvoid/span Main() /span/span { span stylecolor:blackspan stylecolor:black span stylecolor:#0000ffstring/span s2 span stylecolor:#006080ab/span; /span/span s2 c; span stylecolor:blackspan stylecolor:black /span/span Console.WriteLine(string.IsInterned(s2) ?? null); span stylecolor:blackspan stylecolor:black /span/span string s1 abc; span stylecolor:blackspan stylecolor:black }/span/span 你的答案怎么是我们还是接着迎接挑战 span stylecolor:blackspan stylecolor:black span stylecolor:#008000// Release : code06, 2008/08/20 /span/span/span // Author : Anytao, http://www.anytao.com span stylecolor:blackspan stylecolor:black span stylecolor:#0000ffstatic/span span stylecolor:#0000ffvoid/span Main() /span/span { span stylecolor:blackspan stylecolor:black span stylecolor:#0000ffstring/span s2 span stylecolor:#006080ab/span; /span/span s2 c; span stylecolor:blackspan stylecolor:black /span/span Console.WriteLine(string.IsInterned(s2) ?? null); span stylecolor:blackspan stylecolor:black /span/span string s1 GetStr(); span stylecolor:blackspan stylecolor:black } /span/span span stylecolor:blackspan stylecolor:black span stylecolor:#0000ffprivate/span span stylecolor:#0000ffstatic/span span stylecolor:#0000ffstring/span GetStr() /span/span { span stylecolor:blackspan stylecolor:black span stylecolor:#0000ffreturn/span span stylecolor:#006080abc/span; /span/span } 这是第二关了你的思考肯定还在继续我们第三关也呼之欲出 span stylecolor:blackspan stylecolor:black span stylecolor:#008000// Release : code07, 2008/08/20 /span/span/span // Author : Anytao, http://www.anytao.com span stylecolor:blackspan stylecolor:black span stylecolor:#0000ffpublic/span span stylecolor:#0000ffconst/span span stylecolor:#0000ffstring/span s1 span stylecolor:#006080abc/span; /span/span span stylecolor:blackspan stylecolor:black span stylecolor:#0000ffstatic/span span stylecolor:#0000ffvoid/span Main() /span/span { span stylecolor:blackspan stylecolor:black span stylecolor:#0000ffstring/span s2 span stylecolor:#006080ab/span; /span/span s2 c; span stylecolor:blackspan stylecolor:black /span/span Console.WriteLine(string.IsInterned(s2) ?? null); span stylecolor:blackspan stylecolor:black }/span/span 最后一个冲出藩篱 span stylecolor:blackspan stylecolor:black span stylecolor:#008000// Release : code08, 2008/08/20 /span/span/span // Author : Anytao, http://www.anytao.com span stylecolor:blackspan stylecolor:black span stylecolor:#0000ffpublic/span span stylecolor:#0000ffstatic/span span stylecolor:#0000ffstring/span s1 span stylecolor:#006080abc/span; /span/span span stylecolor:blackspan stylecolor:black span stylecolor:#0000ffstatic/span span stylecolor:#0000ffvoid/span Main() /span/span { span stylecolor:blackspan stylecolor:black span stylecolor:#0000ffstring/span s2 span stylecolor:#006080ab/span; /span/span s2 c; span stylecolor:blackspan stylecolor:black /span/span Console.WriteLine(string.IsInterned(s2) ?? null); span stylecolor:blackspan stylecolor:black }/span/span 过关斩将三轮PK是英雄比高。不管怎样你的答案和思考肯定会让大家对string刮目相看是否和你一直以来的认识统一呢在此感谢KiMoGiGi 给我的启示。有了问题我们更需要的是思考、探讨和反思。
2 欲求思考
欲求思考则从基本开始对于理解整个string intern机制是大有裨益的因此深入的第一步就从基本概念开始。随着我们分析的层层深入就会发现看似曲折的结果原来不过如此而已这正是技术探求的最佳方式。
什么是string
什么是string呢提起这个问题我想下面的图例可以给出一点启示 string在本质上就是一连串的有顺序的字符集合。
简单的说string就是char[]而在.NET中string头一回具有了类的概念暗合了.NET一切皆为对象的大一统格局。回归本质我们重新审视如此另类而多彩的string你会不禁明白string本质上就是一个16位Unicode字符数组。打开string的Disassemble代码我们可直击其本质 span stylecolor:blackspan stylecolor:black [Serializable, ComVisible(span stylecolor:#0000fftrue/span)]/span/span public sealed class String : IComparable, ICloneable, IConvertible, IComparablestring, IEnumerablechar, IEnumerable, IEquatablestring span stylecolor:blackspan stylecolor:black {/span/span } 结合string的定义我们可以看出其基本的特性主要包括
引用类型string本质上是引用类型相关内容参考《你必须知道的.NET》 对值类型和引用类型的讨论。字符串恒等性。字符串驻留性本文的研究重点。密封性由sealed关键字可见sealed特性为实现字符串恒等性和字符串驻留机制提供了基础保证具体的原因参见《你必须知道的.NET》 关于string的相关论述。
关于这些特性并非本文关注的热点还有大量的命题值得我们关注总结起来还可包括
字符串比较以等价规则而非恒等规则进行比较。常用方法Trim()、ToLow()、Replace()、Split()、PadRight()、SubString()和Join()格式化。转移字符。StringBuilder另一个重要的话题。Encoding编码。Culture Internationalization语言文化。overloads 重载。
由此可知string真是一个丰富而多彩的技术仓库饱含了.NET技术中很多精髓与技巧我们不可能在本文中尽述其然更多的论述和分析可以参考以下信息 快捷参考 关你可以参考 string的更多技术与规则可以参考《你必须知道的.NET》 8.3节“如此特殊大话String”等价规则和恒等规则可以参考《你必须知道的.NET》 8.2节“规则而定对象判等” www.anytao.com 接下来本文的主题闪亮登场。
什么是字符串驻留String Interning
回归经典我们首先给出MSDN对于字符串驻留的一点讨论
公共语言运行库通过维护一个表来存放字符串该表称为拘留池它包含程序中以编程方式声明或创建的每个唯一的字符串的一个引用。因此具有特定值的字符串的实例在系统中只有一个。
例如如果将同一字符串分配给几个变量运行库就会从拘留池中检索对该字符串的相同引用并将它分配给各个变量。
之所以将string这个熟悉的命题拿出来造轮子并不是再造个轮子自己陶醉。关于string的轮子实在太多了而且个个不顺眼它就像编程的精灵四处可见随处都有。string是如此的重要以至于CLR必须以特殊的方式来实现对string类型的管理、存取和布局在这些复杂的特殊表象中字符串驻留机制是string特殊性的集中体现它的基本原理可以概括为
CLR维护一个类似于哈希表的内部结构用于维护对于字符串的统一管理。但JIT编译时CLR首先查找哈希表如果没有找到匹配的字符串记录则在托管堆中创建新的string实例并为哈希表添加一个键值对记录下一次查找相同string时则只返回该记录的值给第二次创建的string对象。通过这种方式字符串驻留机制有效实现了对string的池管理节省了大量的内存空间。
详细的字符串驻留机制敬请参考 快捷参考 关于字符串驻留机制的详细过程不是本文所要解决的主要问题你可以参考 《你必须知道的.NET》 8.3节“如此特殊大话String” 中的详细分析Artech [原创]再说String www.anytao.com 我们可以从code01尽情领略字符串驻留机制的基本原理然而关于字符串驻留并不是几句简单原理就能全面概括的问题。
注意动态创建的字符串是不执行字符串驻留机制的例如通过 span stylecolor:blackspan stylecolor:black span stylecolor:#008000// Release : code09, 2008/08/25 /span/span/span // Author : Anytao, http://www.anytao.com span stylecolor:blackspan stylecolor:black span stylecolor:#0000ffstatic/span span stylecolor:#0000ffvoid/span Main()/span/span { span stylecolor:blackspan stylecolor:black span stylecolor:#0000ffstring/span s1 span stylecolor:#006080abc/span;/span/span string s2 ab; span stylecolor:blackspan stylecolor:black span stylecolor:#0000ffstring/span s3 s2 span stylecolor:#006080c/span;/span/span span stylecolor:blackspan stylecolor:black Console.WriteLine(ReferenceEquals(s1, s3));/span/span } 但是对于“动态”二字的把握并非一件简单的事情什么情况下执行字符串驻留而什么时候不会执行字符串驻留在.NET spec中我并没有找出足够精确的正解来阐释这个问题例如code06示例中string s1 GetStr(); 的位置很大程度上决定了是否执行字符串驻留条件从code06示例的结果可见string.IsInterned(s2)并未收获返回“abc”的预期结果而下面的示例则又给出意想不到的答案 span stylecolor:blackspan stylecolor:black span stylecolor:#008000// Release : code10, 2008/08/25 /span/span/span // Author : Anytao, http://www.anytao.com span stylecolor:blackspan stylecolor:black span stylecolor:#0000ffstatic/span span stylecolor:#0000ffvoid/span Main()/span/span { span stylecolor:blackspan stylecolor:black span stylecolor:#008000//在这个位置返回abc/span/span/span string s1 GetStr(); span stylecolor:blackspan stylecolor:black /span/span string s2 ab; span stylecolor:blackspan stylecolor:black s2 span stylecolor:#006080c/span;/span/span Console.WriteLine(string.IsInterned(s2) ?? null); span stylecolor:blackspan stylecolor:black }/span/span span stylecolor:blackspan stylecolor:black span stylecolor:#0000ffprivate/span span stylecolor:#0000ffstatic/span span stylecolor:#0000ffstring/span GetStr()/span/span { span stylecolor:blackspan stylecolor:black span stylecolor:#0000ffreturn/span span stylecolor:#006080abc/span;/span/span } 对比code06和code10我们发现不同的只是string s1 GetStr(); 的位置而结果却大相径庭。
为什么
位置的不同而导致触发字符串驻留机制是否执行的条件不同这正是我们通过实例反向验证的最佳体现。那么你的思考呢
这些看似熟悉的问题其实都值得推敲本文没有太多的精力兼顾所有只能在边缘之余探讨一下遗留在字符串驻留机制中一些并不是很清楚的问题算是对字符串驻留机制的进一步探讨主要包括
CLR的加载过程。intern pool在什么时候创建如何创建驻留机制的简述。方法的调用过程。介绍IsInterned和Intern方法。string intern的失效和弊端。
以解决本文开题的几个典型的问题同时顺便解答KiMoGiGi在To 王涛 的问题中提出的问题。下面我们一一揭开这些问题的神秘面纱。
作为字符串驻留机制探讨的第一篇我们从问题出发引出对于字符串驻留的定义和概念在未来的篇章中除了说明上述问题之外我们还将力图解释开篇8个示例的个中结果并对可能的情况和问题进行一些对比性的推敲。
事实上由string intern而引发的技术论题还有很多值得我们品味和玩味这也正是这个本文及其后续篇章力图做出的努力。 敬请期待本篇后文。。。 Anytao | 2008-08-27 | 你必须知道的.NET
http://www.anytao.com/ | Blog: http://anytao.cnblogs.com/ | Anytao原创作品转贴请注明作者和出处留此信息。 特别鸣谢
Jeffery Richter对于我的问题Jeffery先生及时给出自己的见解让我顿时感受到大师的品格。
KiMoGiGi是他的问题带来本文的思考这些难得的线索构成了我们进行探讨的基础话题巧妇难为无米之炊因此需要特别感谢。 参考文献
BookMartin FowlerRefactoring: Improving the Design of Existing Code
cnbloghttp://www.cnblogs.com/flier/archive/2004/07/08/22307.html
cnbloghttp://www.cnblogs.com/artech/archive/2007/05/31/765773.html #11楼 2008-08-27 09:52 信110
const string 是编译时的硬绑定 string ,static string 是运行时的软驻留跟方法执行顺序相关。 临时产生的string不参与驻留,可能跟使用频率有关。 static void Main(string[] args) { GetStr(); string s2 ab; s2 c; Console.WriteLine(string.IsInterned(s2) ?? null); } private static void GetStr() { string a abc;} GetStr()调用位置不同结果不同是不是说明了驻留和方法执行顺序的关系 以上是自己的看法应该不对 呵呵
#17楼 [楼主] 2008-08-27 10:16 Anytao
丁学 驻留池、拘留池看自己的理解和习惯吧。MSDN上的说法称为“拘留池”CLR via c#上的说法是“驻留池”我更喜欢后者也更符合Intern的语义。 www.anytao.com看来要转dns了。
支持(0) 反对(0) #36楼 [楼主] 2008-08-28 09:55 Anytao
sa1 snippet compiler 2008下的测试我没有进行需要进一步看看结果谢谢你的提醒。 关于字符串的回收问题其实是下一篇要讨论的重点问题通过驻留池的创建过程你会有清晰的认识。不过在此可以讨论一下答案那就是string intern是不受GC控制的它的生命周期等同于其整个Process。
支持(0) 反对(0) #37楼 2008-08-28 17:12 Michaelkira
static void Main(string[] args) { string s2 ab; s2 c; Console.WriteLine(string.IsInterned(s2) ?? null); string s1 GetStr(); Console.ReadLine(); } private static string GetStr() { string temp abc; return abc; } 改成这样的话依然显示null那个人就能把它理解成static方法中的string变量不会被选入拘留池这样做的原因可能与static方法中变量所处的内存空间有关系而const变量在编译时就直接被替换也就不存在内存应用是这样理解吗
支持(0) 反对(0) #38楼 2008-08-29 22:03 I Love Asp.NET
--引用-------------------------------------------------- 梁逸晨: 世间有两位大师造福人类一位是楼主一位是李战。楼主的研究可谓登峰造极。岂是一个好字可说得清。 -------------------------------------------------------- 顶一个中国太缺少这样的人了。多几个中国的软件业肯定会更蓬勃
支持(0) 反对(0) #39楼 2008-09-01 12:59 yellowyu
按TAO哥你上面的话讲 但JIT编译时CLR首先查找哈希表如果没有找到匹配的字符串记录则在托管堆中创建新的string实例并为哈希表添加一个键值对记录下一次查找相同string时则只返回该记录的值给第二次创建的string对象。 那此时返回NULL是由于在哈希表里找不到哈希表里并未保存“abc” public const string s1 abc; static void Main() { string s2 ab; s2 c; Console.WriteLine(string.IsInterned(s2) ?? null); } 可依然想不通为什么S1不是在这函数之前难道S1赋ABC是在MAIN函数执行之后。。而string.IsInterned(abc )或 string.IsInterned(s1) 都能返回abc
支持(0) 反对(0) #40楼 2008-09-01 19:44 yellowyu
恕小弟天资愚笨还有一点也始终想不明白 接上一问 string s2 ab; s2 c; Console.WriteLine(string.IsInterned(s2)null ?true :false); 此时打印为true即string.IsInterned(s2)返为null 好小弟就当他是找不到拘留池里没办法找到所以为NULL 问二: 那接下来 string s2 ab; s2 c; Console.WriteLine(string.IsInterned(s2)null ?true :false); Console.WriteLine({0}, object.ReferenceEquals(s1, string.IsInterned(s2))); 此时却是 false true 即第一个返回false,即找到了并不是NULL此时却能找到..... 而第二个返回值为true string.IsInterned(s2)返回的字符串的引用与S1引用相等 那我拆出来 string s2 ab; s2 c; Console.WriteLine(string.IsInterned(s2)null ?true :false); Console.WriteLine( {0}, object.ReferenceEquals(s1,s2)); 返回false false 第一个返回FALSE即不为空即池里面存在 那接下来为什么又是FALSE即是两个相同的字符串在内存中的引用不一致哦,是这样吗 唯一的想法就是string.IsInterned(s2)与s2是不一样的引用的对象是这样吗 还有最后一个问题 string s2 ab; s2 c; Console.WriteLine({0}, object.ReferenceEquals(s1, string.IsInterned(s2))); 按上面的string.IsInterned(s2)返回的结果是null ,那此时object.ReferenceEquals(s1, string.IsInterned(s2)));应该等同于 object.ReferenceEquals(s1, null)); 可结果却是返回true又回到了一开始的地方,跟一开始的地方有点。。。。差别 MSDN解: 返回值 如果 str 位于公共语言运行库“拘留池”中则为对它的 String 引用否则为空引用
支持(0) 反对(0) #41楼 2008-09-01 21:27 Blindsniper
Funny... 我的猜测不知道有几个对... string s1 abc; string s2 ab; s2 c; string.IsInterned(s2)实际上返回的是s1不是s2自己。我觉得是因为IsInterned()方法是去intern pool的Hashtable里找是否有一个key值为abc的地址那么找到的value当然是s1的地址用object.ReferenceEquals方法看得很清楚s2分配的托管堆地址肯定没有在inten pool的Hashtable里。 code05code06和code10在IL里code05直接调用ldstr abc而code06和code10是动态调用别的方法而code06是在判断s2之后调用code10是在判断s2之前 所以我估计就是这几个地方造成了结果不一致... code07, 用IL看了看因为在Main方法里面没有const s1的引用所以貌似未对其进行intern(如果在其他方法中调用s1貌似结果仍然为null,我猜是因为垃圾回收把干掉了不过很怀疑这一点没仔细考虑...)。如果在Main里面加一个string test s1的话它的效果基本上跟code05一样的都是要ldstr abc所以在这个时候自然string.IsInterned(s2)不为null而是abc. code08因为是static所以应该是直接驻留了...
支持(0) 反对(0) #42楼 2008-09-03 09:24 2
.net 框架 一书中对这个讲的比较详细的
支持(0) 反对(0) #43楼 2008-09-03 17:41 Robin Zhang
期待下文
支持(0) 反对(0) #44楼 [楼主] 2008-09-03 18:41 Anytao
Michaelkira 这实际上是我想在下篇中力图澄清的问题但是现在阶段还没有完全了解透彻有一些问题还只能用“本来就这样”式的万能答案来回答所以我希望对此再进行一些探讨和分析希望有更近距离的答案。
支持(0) 反对(0) #45楼 [楼主] 2008-09-03 18:41 Anytao
I Love Asp.NET :-)
支持(0) 反对(0) #46楼 2008-10-16 12:45 lauer
关注中。。。
支持(0) 反对(0) #47楼 2009-01-20 17:34 痘痘熊
俺也测试了一下和俺的想象很类似如果是没有对原生字符串进行操作直接赋值例如 string s XXXX; 或者 return XXXXX;这样的字符串会被加入intern pool中但是如果对其进行了操作例如字符串连接或者其他处理显然就不再intern中了而是在普通的内存堆里头。这么做的好处很明显intern pool中保留的字符串就像是零件是很小的但是可能到处都能用到的片段。例如 string s1 Hello; string s2 Hello; 这时internal pool中只有一个Hello但是s1和s2都引用这个Hello。这个时候如果s2 You;s1 You;那么internal pool中就增加了一个You但是原来的Hello还是存在。此时可以这么看 string str1 Hello; string str2 Hello; str1 You; str2 You; Console.WriteLine(string.IsInterned(str1) ?? null); Console.WriteLine(string.IsInterned(str2) ?? null); Console.WriteLine(string.IsInterned(Hello) ?? null);
支持(0) 反对(0) #48楼 2009-01-20 17:43 痘痘熊
抱歉测试有误字符串连接后仍然是在internal pool中的。是变量和原生字符串互操作才会不在其中XX YY这样的操作仍然是可以的。还有stringbuilder的tostring()也是可以的。 static void Main(string[] args) { Console.WriteLine(string.IsInterned(Hello X) ?? null); string str1 Hello; string str2 Hello; string str3 GetABC(); str1 You; str2 You; string str4 str1 X; Console.WriteLine(string.IsInterned(str1) ?? null); Console.WriteLine(string.IsInterned(str2) ?? null); Console.WriteLine(string.IsInterned(str3) ?? null); Console.WriteLine(string.IsInterned(str4) ?? null); Console.WriteLine(string.IsInterned(Hello) ?? null); StringBuilder sb new StringBuilder(Hello); Console.WriteLine(string.IsInterned(sb.ToString()) ?? null); } public static string GetABC() { return Hello X; } }
支持(0) 反对(0) #49楼 2009-01-20 18:11 痘痘熊
貌似编译时能生成的字符串自动加入intern poolruntime时生成的字符串在第一次赋值的时候加入intern pool……另外这里有intern的性能测试http://dotnetperls.com/Content/string-Intern.aspx 只是不懂的是如果有大量大量大量的字符串赋值会占用多大的空间呢
支持(0) 反对(0) #50楼 2009-01-20 18:41 痘痘熊
yellowyu 估计你的猜测是对的string和string.IsInterned引用的是不同的东西。例如你动态创建了一个字符串str你要使用string.Intern(str)才可以把这个字符串加入intern pool当中。详见http://msdn.microsoft.com/en-us/library/system.string.intern.aspx 中的Remark。另外系统定义为这东西就是用来装string literals的。而msdn对string literals的定义就是或者引起来的东西。http://msdn.microsoft.com/en-us/library/aa691090.aspx 也就是说不是这两个东西的就不是string literals也就不可能加进去intern pool。另外有迹象表明这个intern pool很可能是多个程序共享的“the memory allocated for interned String objects is not likely be released until the common language runtime (CLR) terminates. The reason is that the CLRs reference to the interned String object can persist after your application, or even your application domain, terminates纯属猜测哈哈哈。另外从上面那个性能测试的代码里你也可以看出来这两个东西引用的的确不是同一个东西。:)
#51楼 2009-05-20 14:41 wang2855
非常感谢王涛的大作.说下自己的理解: 因为:string s1 GetStr();是在赋值的时候驻留的,所以如果这句放在显示 Console.WriteLine(string.IsInterned(s2) ?? null) 前,则一定不为null. 如果放在后面则为null. 我在测试的时候发现:有时候违背此规律,后来想想可能是程序结束了但是内存没释放,此时修改s1 为:abcddee结果再次验证了我的猜想. 参考文章:http://hi.baidu.com/mkjmmc/blog/item/9406fd434fd35d1772f05d54.html 如有不对请指正.谢谢.