问题 .NET是否为每个程序集创建一个字符串实习池?


我有一种情况,我会遇到很多重复的字符串,这些字符串会在内存中持续很长时间。我想用 String.Intern 但我不想入侵任何潜在的应用程序资源,因为我的项目是一个库。这个怎么用?


9979
2017-10-24 09:02


起源

嗯,实习字符串是引用计数的。保存引用的主要对象是AppDomain拥有的表(类似于HashSet)。卸载appdomain会清空表,减少引用计数。绝大多数(如果不是全部)字符串应该消失。没有“入侵”的危险。 - Hans Passant
有点偏离主题,但在搜索有关字符串实习的各种信息时,我发现了这篇非常有意义的博客文章: blog.benoitblanchon.fr/modify-intern-pool 。另请参见相关的源代码。 - AFract


答案:


字符串的实习表是 CLR作用域

首先,不太可能为interned String对象分配内存   在公共语言运行库(CLR)终止之前一直被释放。该   原因是CLR对interned String对象的引用可以   在您的申请,甚至您的申请域之后坚持,   终止。

因此,不仅实习表不是特定于装配,而且它可以比装配更长。好消息是重复的字符串不会成为问题,因为相同的文字字符串一旦被实现就具有相同的引用。所以 Intern推荐:

公共语言运行库通过维护a来保存字符串存储   表,称为实习池,包含单个引用   以编程方式声明或创建的每个唯一文字字符串   你的计划。因此,带有一个文字字符串的实例   特定值仅在系统中存在一次。

string s1 = "MyTest"; 
string s2 = new StringBuilder().Append("My").Append("Test").ToString(); 
string s3 = String.Intern(s2); 
Console.WriteLine((Object)s2==(Object)s1); // Different references.
Console.WriteLine((Object)s3==(Object)s1); // The same reference.

11
2017-10-24 09:05