Tag: large object heap

第3代对象与大对象堆之间的区别

大对象堆和GC第3代对象有什么区别?

RegEx,StringBuilder和大对象堆碎片

如何在不引起LOH碎片的情况下在大字符串中运行大量RegExes(以查找匹配项)? 它是.NET Framework 4.0所以我使用StringBuilder所以它不在LOH中,但是一旦我需要在它上面运行RegEx,我必须调用StringBuilder.ToString() ,这意味着它将在LOH中。 有没有解决这个问题的方法? 拥有一个长期运行的应用程序几乎不可能处理大字符串和像这样的RegExes。 解决这个问题的想法: 在考虑这个问题时,我想我发现了一个肮脏的解决方案。 在给定的时间我只有5个字符串,这5个字符串(大于85KB)将传递给RegEx.Match 。 由于碎片发生是因为新对象不适合LOH中的空白空间,这应该可以解决问题: PadRight所有字符串最多。 接受大小,比方说1024KB(我可能需要用StringBuider来做这个) 通过这样做,所有新字符串将适合已经清空的内存,因为先前的字符串已经超出范围 不会有任何碎片,因为对象大小总是相同的,因此我只会在给定时间分配1024 * 5,并且LOH中的这些空间将在这些字符串之间共享。 我想这个设计的最大问题是如果其他大对象在LOH中分配这个位置会导致应用程序分配大量1024 KB字符串,甚至更糟糕的碎片。 但是,如果没有实际创建一个不在固定内存地址中的新字符串,我怎样才能将固定字符串发送到RegEx? 关于这个理论的任何想法? (不幸的是我无法轻易地重现问题,我通常会尝试使用内存分析器来观察更改,并且不确定我可以为此编写哪种隔离测试用例)

读取二进制文件时避免LOH

此问题是将许多二进制文件传输到SQL Server数据库的有效方法的后续操作 我最初问为什么使用File.ReadAllBytes导致快速内存使用,并且使用该方法得出结论将数据放在大对象堆上,这在运行时期间无法轻易回收。 我现在的问题是如何避免这种情况? using (var fs = new FileStream(path, FileMode.Open)) { using (var ms = new MemoryStream()) { byte[] buffer = new byte[2048]; int bytesRead; while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) > 0) { ms.Write(buffer, 0, bytesRead); } return new CustomFile { FileValue = ms.ToArray() }; } } 下面的代码旨在通过以块的forms而不是一次性读取文件来解决问题,但它似乎有同样的问题。

使用Protobuf-net序列化分块字节数组的内存使用情况

在我们的应用程序中,我们有一些数据结构,其中包含一个分块的字节列表(当前公开为List )。 我们将字节大块化,因为如果我们允许将字节数组放在大对象堆上,那么随着时间的推移,我们会遇到内存碎片。 我们还开始使用Protobuf-net来序列化这些结构,使用我们自己生成的序列化DLL。 但是我们注意到Protobuf-net在序列化时会创建非常大的内存缓冲区。 浏览源代码时,似乎它可能无法刷新其内部缓冲区,直到整个List结构被写入,因为它需要在缓冲区前面写入总长度。 不幸的是,这首先解决了我们的工作,首先将字节分块,最终由于内存碎片而给我们OutOfMemoryExceptions(exception发生在Protobuf-net尝试将缓冲区扩展到84k以上时,这显然是在LOH,我们的整体进程内存使用率相当低。 如果我对Protobuf-net工作原理的分析是正确的,那么有没有解决这个问题的方法呢? 更新 根据Marc的回答,这是我尝试过的: [ProtoContract] [ProtoInclude(1, typeof(A), DataFormat = DataFormat.Group)] public class ABase { } [ProtoContract] public class A : ABase { [ProtoMember(1, DataFormat = DataFormat.Group)] public BB { get; set; } } [ProtoContract] public class B { [ProtoMember(1, DataFormat = DataFormat.Group)] public List Data { get; set; } […]