【问题标题】:Pre-allocate some memory in Large Object Heap memory在大对象堆内存中预分配一些内存
【发布时间】:2011-09-13 01:13:00
【问题描述】:

我正在开发一个 C# 应用程序,该应用程序正面临内存紧缩,因为许多对象正在大对象堆中分配内存。

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

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

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

所以,我希望在内存中分配一堆,比如说 100 KB,每当我读取一个新文件并将其转换为字符串时,就会分配这 100 KB。

【问题讨论】:

  • 考虑使用StringBuilder,它基本上是一个可变字符串。
  • 你为什么一遍又一遍地分配相同的字符串?如果您创建过一次,则只需将其传递给所有消费者。
  • 为什么你认为 LOH 碎片是你的问题?
  • 为什么你的代码会一次读取内存中的所有文件内容?您不能以较小的块读取文件吗?
  • 不是同一个字符串,因为我在处理不同的文件,所以内容会不同。

标签: c# .net memory-management fragmentation large-object-heap


【解决方案1】:

您应该使用StringBuilder 对象来处理字符串,因为它是一个可变字符串并且提供了许多处理它的方法。

您是说每个字符串都是一次又一次地创建的。如果由于某种原因必须使用字符串,只需 Intern 它们 - 它们将存储一次,并且不会再次添加到内存堆中

【讨论】:

  • 实习只能工作它大约是相同字符串的很多倍(来自文件)。不太可能。
  • 我已经说了所有的变种
【解决方案2】:

您是否考虑过使用内存映射文件? http://msdn.microsoft.com/en-us/library/dd997372.aspx

我不知道你用字符串做什么,但是有理由不使用流吗?

【讨论】:

    【解决方案3】:

    目前尚不清楚您想对琴弦执行什么样的操作,最好的方法是对最终结果的估计。使用悲观(大)估计,并可能增加一个边际。

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

    var buffer = new StringBuilder(LargestExpectedSize);
    

    这本质上是 LOH 上的预分配。避免(自动)增长 StringBuilders 或 List<>s

    【讨论】:

      猜你喜欢
      • 2012-01-08
      • 2017-11-08
      • 2011-06-03
      • 1970-01-01
      • 2013-08-21
      • 2015-10-15
      • 1970-01-01
      • 2014-03-17
      • 2023-03-03
      相关资源
      最近更新 更多