如何在c#中释放或回收字符串

本文关键字:字符串 释放 | 更新日期: 2023-09-27 18:07:38

我有一个大字符串(例如20MB)。

我现在正在解析这个字符串。问题是c#中的字符串是不可变的;这意味着一旦我创建了一个子字符串,并查看了它,内存就被浪费了。

由于所有的处理,内存被不再使用,不再需要或引用的String对象阻塞;但是,垃圾收集器需要很长时间才能释放它们。

应用程序内存不足。

我可以使用性能较差的club方法,并将几千个调用分散到:

GC.Collect();

无处不在,但这并不能真正解决问题。

创建一个大字符串时,

i知道StringBuilder存在。

i know TextReader存在,可以将String读入char数组。

我需要以某种方式"重用"字符串,使其不再是不可变的,这样我就不必在1k的时候分配千兆字节的内存。

如何在c#中释放或回收字符串

如果您的应用程序即将死亡,那么很可能是因为您仍然有对字符串的引用,而不是因为垃圾收集器未能清除它们。我已经看到它像那样失败,但这是不太可能的。您是否使用了分析器来检查您是否真的一次在内存中有很多字符串?

它的长和短是你不能重用一个字符串来存储不同的数据——这就是不能做。如果你愿意的话,你也可以自己编写类似的代码——但是高效而正确地完成这些的可能性非常小。现在,如果你能提供更多关于你正在做的事情的信息,我们也许能建议一些不使用那么多内存的替代方法。

这个问题差不多有10年了。这些天,请看看ReadOnlySpan -实例化一个从字符串使用AsSpan()方法。然后,您可以应用索引操作符来获取片作为跨度,而无需分配任何新字符串。

考虑到不能重用c# 中的字符串这一事实,我建议使用内存映射文件。您只需将字符串保存在磁盘上,并通过像流一样的映射文件以性能/内存消耗良好的关系处理它。在这种情况下,您重用相同的文件,相同的流,并且只对数据的一小部分(如字符串)进行操作,然后立即将其丢弃。

此解决方案严格取决于您的项目需求,但我认为您可能会认真考虑的解决方案之一,特别是内存消耗将大幅下降,但您将在性能方面"付出"一些东西。

您是否有一些示例代码来测试可能的解决方案是否有效?

一般来说,任何大于85KB的对象都将被分配到大对象堆中,这可能会减少垃圾收集的频率。

而且,如果您真的在给CPU施加压力,那么垃圾收集器可能会减少执行其工作的频率,试图避开您。