C#:相同内容的字符串我听说过一个字符串是不能改变的(不可变的?)。我认为这应该是正确的。但我也听说过,两个内容相同的字符串共享相同的内存空间(或随便你怎么称呼它)。这是对的吗?如果是这样,这是否意味着如果我创建一个包含数千个字符串的列表,如果这些字符串中的大多数彼此相等,它根本不会占用太多空间?编辑:在下面的答案中,我将实习生池称为特定于AppDomain的;我很确定这是我之前观察到的,但是String.Intern的MSDN文档表明整个事情都有一个实习生池,这使得这一点变得更加重要。原始答案(我打算将其添加为评论,但我认为这是一个非常重要的点,需要一个额外的答案......)正如其他人所解释的那样,字符串实习发生在所有字符串文字中,而不是“动态创建”的字符串(例如那些从数据库或文件中读取的,或者使用StringBuilder或String.Format构建的)。但是,我不建议调用String.Intern来绕过后一点:它将在AppDomain的生命周期内填充实习生池。相反,仅使用本地池供您使用。下面是这样一个池的例子:publicclassStringPool{privatereadonlyDictionarycontents=newDictionary();publicstringAdd(stringitem){stringret;如果(!contents.TryGetValue(item,outret)){contents[item]=item;ret=项目;返回ret;然后你可以简单地使用以下内容:stringdata=pool.Add(ReadItemFromDatabase());(请注意,池不是线程安全的;正常使用不需要它。)这样,您可以在不再需要池时立即丢弃它,而不是在内存中永远保留一大串字符串。如果你真的想实现LRU缓存或其他东西,你也可以让它变得更聪明。编辑:只是为了阐明为什么这比使用String.Intern更好......假设您从数据库或日志文件中读取了一堆字符串,处理它们,然后继续执行另一项任务。如果您在这些字符串上调用String.Intern,只要您的AppDomain处于活动状态,它们就永远不会被垃圾回收——甚至可能根本不会。如果您加载多个不同的日志文件,您将逐渐在实习生池中积累字符串,直到您完成或内存不足。相反,我建议使用这种模式:voidProcessLogFile(stringfile){StringPoolpool=newStringPool();//使用池中的字符串处理日志文件}//现在可以对池进行垃圾回收这里你可以获得同一个文件中多个字符串的好处,它们在内存中只存在一次(或者至少通过gen0只存在一次)但你不会污染“全球”资源(实习池)。这或多或少是正确的。它被称为“字符串实习”。字符串文字在内存中只出现一次,每个设置为相同值的变量都指向这个单一的表示形式。但是,在代码中创建的字符串不会自动具体化。http://msmvps.com/blogs/manoj/archive/2004/01/09/1549.aspx如果我没记错的话,代码中硬编码的字符串是单独汇总的。这叫做“Interned”,有一个方法可以查询一个字符串是否是:String.IsInternedMethod在这个页面的“Remarks”下你可以看到:公共语言运行库自动维护一个名为“internpool”的池一个表包含程序中声明的每个唯一文字字符串常量的单个实例,以及以编程方式添加的任何唯一字符串实例。希望这对您有所帮助,如果我错了,请纠正我。Mathias为了让字符串“共享”它们的内存位置,是在一个内部池中实现它们,该池包含对程序中以编程方式声明或创建的每个唯一文字字符串的单个引用。请注意,代码中的所有字符串文字都会自动具体化。以上是C#学习教程:C#:所有内容相同的字符串共享。如果对大家有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
