在大对象堆内存中预分配一些内存

3

我正在开发一个C#应用程序,但是该应用程序面临内存不足的问题,因为许多对象在大对象堆中分配了内存。

我的C#应用程序需要处理许多大文件(作为字符串对象),因此这种字符串类型对象的内存会一次又一次地从大对象堆中分配(从而导致LOH碎片化)。

由于字符串是不可变对象,因此始终会为该对象分配新的LOH内存。我的问题是,是否有一种方法可以在大对象堆中预先分配一些内存,并始终将同一内存分配给字符串对象。

更详细的解释如下: 正如我所提到的,我正在处理这些大文件。为了进行处理,我必须将其转换为字符串。即使我使用stringBuilder,也没有太大帮助,因为一旦我将其转换为String,就会为其分配单独的内存空间在LOH中。

因此,我希望能够预先在内存中分配一些空间,比如说100 KB,每当我读取一个新文件并将其转换为字符串时,这100 KB就被分配出去。


2
考虑使用 StringBuilder,它基本上是一个可变字符串。 - Lasse Espeholt
5
为什么你一遍又一遍地分配同一个字符串?如果你已经创建了它,那就把它传递给所有的使用者。 - Andrei
2
你为什么认为LOH碎片化是你的问题? - svick
1
为什么你的代码一次性读取了整个文件内容?难道你不能分块读取文件吗? - Dan
这不是同一个字符串,因为我正在处理不同的文件,内容会有所不同。 - Kunal
显示剩余2条评论
3个回答

3
您应该使用可变字符串对象StringBuilder来处理字符串,因为它提供了许多方法来操作字符串。
您说每个字符串都会被不断地创建。如果出于某种原因必须使用字符串,只需将其Intern化-它们将被存储一次,而不会再次添加到内存堆中。

2
实习只有在多次使用相同的字符串(来自文件)时才有效。这种情况并不太可能发生。 - H H
我刚刚说了所有的变体。 - VMAtm

1

1

不清楚您想对这些字符串进行什么操作,最好的方法是估计最终结果。请使用悲观(较大)的估计,并可能添加一些余量。

然后使用容量参数创建一个 StringBuilder:

var buffer = new StringBuilder(LargestExpectedSize);

这实际上是在 LOH 上进行的预分配。避免 StringBuilder 或 List<> 的(自动)增长。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接