【发布时间】:2011-12-22 15:53:33
【问题描述】:
如何在大字符串中运行大量 RegEx(以查找匹配项)而不导致 LOH 碎片?
它是 .NET Framework 4.0,所以我使用的是 StringBuilder,所以它不在 LOH 中,但是一旦我需要在其上运行 RegEx,我必须调用 StringBuilder.ToString(),这意味着它将在 LOH 中.
这个问题有什么解决办法吗?像这样处理大字符串和正则表达式的长时间运行的应用程序几乎是不可能的。
解决这个问题的思路:
在思考这个问题时,我想我找到了一个肮脏的解决方案。
在给定时间我只有 5 个字符串,这 5 个字符串(大于 85KB)将被传递给RegEx.Match。
由于新对象不适合 LOH 中的空白空间而发生碎片,这应该可以解决问题:
-
PadRight最大字符串。可接受的大小,假设为 1024KB(我可能需要使用StringBuider执行此操作) - 通过这样做,所有新字符串都将适合已清空的内存,因为之前的字符串已经超出范围
- 不会有任何碎片,因为对象大小始终相同,因此我只会在给定时间分配 1024*5,而 LOH 中的这些空间将在这些字符串之间共享。
我想这个设计的最大问题是如果其他大对象在 LOH 中分配这个位置会导致应用程序分配大量 1024 KB 的字符串可能会产生更严重的碎片。 fixed 语句可能会有所帮助,但是如何在不实际创建不在固定内存地址中的新字符串的情况下将固定字符串发送到 RegEx?
对这个理论有什么想法吗? (不幸的是我不能轻易地重现这个问题,我通常会尝试使用内存分析器来观察变化,并且不确定我可以为此编写什么样的隔离测试用例)
【问题讨论】:
-
您确定大对象堆正在变得碎片化吗?我对大型(数百千字节)字符串做了很多工作,但从未遇到过 LOH 碎片问题。
-
是的,我确定。应用程序需要占用大量内存并长时间运行才能看到它的实际影响。如果您确实进行了内存分析,您可能会发现它对您有影响,但不足以让您的应用崩溃。
-
是的,很简单。一百美元可以给你买一个 64 位的操作系统。没有任何一种编程工作可以与之匹敌。
-
@Hans 我猜你是一个服务器端程序员 :) 这是一个被运送到我无法控制的计算机上的工具。你想让我告诉我的用户他们必须使用 x64 吗?因为不只是100美元?或者可能只是将客户群限制为 x64-Win 7 用户?这更容易,不是吗?
-
任何软件供应商都会发布先决条件。需要Windows,不能使用Apple,必须能够运行.NET、yada磁盘空间、yada RAM等。这没有什么不同,x64 没有什么特别之处。戴尔过去 3 年的默认选择,无需额外费用。
标签: c# regex memory .net-4.0 large-object-heap