标签: large-object-heap

在会话中缓存搜索结果与保持大对象堆清洁

好吧,所以我一直在研究ASP.NET项目一段时间,似乎我做了一些糟糕的设计选择,这些选择后来困扰着我,因为项目在包含的数据方面不断变得越来越大.

在阅读了.NET内存管理之后,我想我已经找到了一整套潜在的原因.由于我正在做的事情并不是特别特别,我想知道是否有一个标准模式来实现我想要做的事情,我错过了.

所以我有一个(有点昂贵的查询)产生1到20000个结果之间的东西.在后续请求中,我们可能只是在结果集中进行分页,因此我将此结果存储在会话中.会话是InProc.我在想:

  • 是否有意义a)将结果b)存储在会话c)进程中?我想要(a)的速度.我不知道是否有一种更有效的方式,而不是用户(b)存储它,如果我使用更复杂的状态服务器 - 它不是更慢(c)?或者这可能是解决方案,更快速地处理那些大对象而不是将最后的结果集保留在RAM中直到会话到期?

  • 如果任何结果集> ~20000行最终可能搞乱了LOH,是否有一种通用的方法可以解决这个问题?

我知道这个问题略有不足.我刚刚意识到我的整体设计可能存在缺陷(可扩展性),而我只是想估计它究竟有多么缺陷.我希望可以收集一些关于标准模式的提示,然后将其变成一个普遍有用的问题.

c# asp.net session-state out-of-memory large-object-heap

6
推荐指数
1
解决办法
1237
查看次数

如何序列化大型集合

我正在使用一个包含超过五百万个项目的列表和词典的系统,其中每个项目通常是一个具有多达90个原始属性的平面dto.使用protobuf-net将集合持久保存到磁盘,以实现弹性和子序列处理.

不出所料,我们在处理和序列化过程中遇到了LOH.

我们可以在处理过程中使用ConcurrentBag等来避免LOH,但是在序列化时我们仍遇到问题.

目前,集合中的项目被批量分组为1000个并且并行地序列化为内存流.每个字节数组都放在一个并发队列中,以便稍后写入文件流.

虽然我明白这是在尝试做什么,但它似乎过于复杂.感觉就像protobuf本身应该有一些东西可以在不使用LOH的情况下处理大量的收藏.

我希望我犯了一个小学生错误 - 我忽略了一些设置.否则,我将寻求编写自定义二进制读取器/写入器.

我应该指出我们正在使用4.0,希望尽快转向4.5但是我们意识到尽管GC有所改进,我们仍然无法解决这个问题.

任何帮助赞赏.

c# serialization protobuf-net large-object-heap

6
推荐指数
1
解决办法
737
查看次数

广泛使用LOH会导致严重的性能问题

我们在Server 2012上使用了WebApi 2,.NET 4.5的Web服务.我们看到偶尔的延迟增加10-30ms,没有充分的理由.我们能够找到有问题的代码片段到LOH和GC.

有一些文本我们将其转换为UTF8字节表示(实际上,我们使用的序列化库就是这样).只要文本短于85000字节,延迟就会稳定且短暂:平均为~0.2 ms,为99%.一旦超过85000边界,平均延迟增加到约1ms,而99%跳跃到16-20ms.Profiler显示大部分时间都花在了GC上.可以肯定的是,如果我在迭代之间放置GC.Collect,测得的延迟会回到0.2ms.

我有两个问题:

  1. 延迟来自哪里?据我所知,LOH没有被压缩.SOH正在被压缩,但没有显示延迟.
  2. 有没有一种实用的方法来解决这个问题?请注意,我无法控制数据的大小并使其变小.

-

public void PerfTestMeasureGetBytes()
{
    var text = File.ReadAllText(@"C:\Temp\ContactsModelsInferences.txt");
    var smallText = text.Substring(0, 85000 + 100);
    int count = 1000;
    List<double> latencies = new List<double>(count);
    for (int i = 0; i < count; i++)
    {
        Stopwatch sw = new Stopwatch();
        sw.Start();
        var bytes = Encoding.UTF8.GetBytes(smallText);
        sw.Stop();
        latencies.Add(sw.Elapsed.TotalMilliseconds);

        //GC.Collect(2, GCCollectionMode.Default, true);
    }

    latencies.Sort();
    Console.WriteLine("Average: {0}", latencies.Average());
    Console.WriteLine("99%: {0}", latencies[(int)(latencies.Count * 0.99)]);
}
Run Code Online (Sandbox Code Playgroud)

c# performance garbage-collection large-object-heap

6
推荐指数
1
解决办法
454
查看次数

C#:GC会收集是否需要内存,还是会给出内存异常?

我的代码中有一个循环,它生成许多byte []数组(每个大约1到2 MB),用数据填充它们,然后丢弃引用.所以,即使参考文献只持有很短的时间,我也可以看到私人工作集的增长.

现在,如果我尝试在循环之后分配一个大型数组(~400 MB),我是否可以获得内存不足异常?或者分配会强制GC收集瞬态数据?

谢谢!

c# garbage-collection memory-management large-object-heap

5
推荐指数
1
解决办法
1031
查看次数

获取 LOH 中的对象实例列表

我在托管堆中存在数百个MyClass实例。其中一些位于大对象堆中。下面是各种堆结构的样子

0:000> !EEHeap -gc
Number of GC Heaps: 1
generation 0 starts at 0x0000000002df9de8
generation 1 starts at 0x0000000002dc6710
generation 2 starts at 0x0000000002a01000
ephemeral segment allocation context: none
 segment     begin allocated  size
0000000002a00000  0000000002a01000  0000000002e3c2c0  0x43b2c0(4436672)
Large object heap starts at 0x0000000012a01000
 segment     begin allocated  size
0000000012a00000  0000000012a01000  000000001a5ed558  0x7bec558(129942872)
000000002a980000  000000002a981000  00000000328110b8  0x7e900b8(132710584)
0000000033e00000  0000000033e01000  000000003bd80d78  0x7f7fd78(133692792)
000000001daf0000  000000001daf1000  0000000025996188  0x7ea5188(132796808)
00000000542b0000  00000000542b1000  000000005a4bf100  0x620e100(102818048)
000000005c2b0000  000000005c2b1000  000000006344df88  0x719cf88(119132040)
000000007fff0000  000000007fff1000  00000000878bfbc0  0x78cebc0(126675904)
Total Size:              Size: …
Run Code Online (Sandbox Code Playgroud)

.net windbg sos large-object-heap sosex

5
推荐指数
1
解决办法
1425
查看次数

方法本地 .NET 对象何时有资格进行 GC?

假设我有一个这样的 C# 方法:(显然不是真正的代码)

byte[] foo()
{
    var a = MethodThatReturns500mbObject();
    var b = MethodThatReturns200mbObject(a);
    byte[] c = MethodThatReturns150mbByteArray(b);
    byte[] d = UnwiselyCopyThatHugeArray(c);
    return d;
}
Run Code Online (Sandbox Code Playgroud)

正如您可以通过命名猜测的那样,这些方法返回的对象是巨大的。每个都需要数百兆字节的总 RAM,尽管前两个对象由数百万个较小的对象组成,而不是像后两个数组那样是一个巨大的块。

我们很快就会将其优化为流式解决方案,但与此同时,我想确保至少我们不会在执行代码以生成后期对象时阻止对早期对象的 GC。

我的问题是:a一旦 MethodThatReturns200mbObject(a) 返回,对象是否有资格进行 GC?如果没有,让 GC 知道有 500MB 存在等待它的最佳方法是什么?

我的问题的核心是 .NET GC 对“此对象没有引用”的判断是否足够聪明,知道返回a后无法引用MethodThatReturns200mbObject(a)。尽管var a理论上仍可用于以后的代码,a但在方法第二行以下的任何地方都没有引用。理论上,编译器可以让 GC 知道它a是未引用的。但在实践中,我不确定它的行为方式。你知道吗?

.net c# garbage-collection memory-management large-object-heap

5
推荐指数
1
解决办法
93
查看次数

大对象堆碎片会导致 64 位进程中的 OutOfMemory 吗?

我正在准备向我的团队介绍 .net GC 和内存。不同的来源讨论了碎片对大对象堆的潜在影响。由于这将是一个有趣的现象,我试图在代码中展示它。

Thomas Weller 提供了这段代码,当尝试将更大的对象分配到 LOH 中的已释放间隙时,它看起来应该会导致 OOM,但由于某种原因它没有发生。LOH 是否在 .net 4.6 中自动压缩?LOH 碎片在 64 位中根本就不是问题吗?

来源:https : //stackoverflow.com/a/30361185/3374994

class Program
{
    static IList<byte[]> small = new List<byte[]>();
    static IList<byte[]> big = new List<byte[]>(); 

static void Main()
{
    int totalMB = 0;
    try
    {
        Console.WriteLine("Allocating memory...");
        while (true)
        {
            big.Add(new byte[10*1024*1024]);
            small.Add(new byte[85000-3*IntPtr.Size]);
            totalMB += 10;
            Console.WriteLine("{0} MB allocated", totalMB);
        }
    }
    catch (OutOfMemoryException)
    {
        Console.WriteLine("Memory is full now. Attach and debug if you like. Press Enter when …
Run Code Online (Sandbox Code Playgroud)

.net c# memory garbage-collection large-object-heap

5
推荐指数
1
解决办法
1247
查看次数

4
推荐指数
1
解决办法
3099
查看次数

.NET 进程的内存转储中有大量无法解释的内存

我无法解释 C# 进程使用的大部分内存。总内存为 10 GB,但总可达和不可达对象总计为 2.5 GB。我想知道这些 7.5 GB 可能是什么?

我正在寻找最可能的解释或方法来找出这种记忆是什么。

这是确切的情况。进程是.NET 4.5.1。它从互联网下载页面并使用机器学习处理它们。内存几乎完全在托管堆中,如 VMMap 所示。这似乎排除了非托管内存泄漏。 在此处输入图片说明

这个过程已经运行了几天,内存慢慢增长。在某些时候,内存为 11 GB。我停止在这个过程中运行的一切。我多次运行垃圾收集,包括大对象堆压缩(间隔一分钟):

GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
GC.Collect();
Run Code Online (Sandbox Code Playgroud)

内存下降到 10 GB。然后我创建转储:

procdump -ma psid

正如预期的那样,转储为 10 GB。

我使用.NET 内存分析器(5.6 版)打开转储。转储显示总共 2.2 GB 可访问对象和 0.3 GB 不可访问对象。剩下的 7.5 GB 可以解释什么?

我一直在想的可能解释:

  • LOH 并没有真正被完全压实
  • 一些内存使用超出了分析器显示的对象

c# memory-profiling large-object-heap

4
推荐指数
1
解决办法
1391
查看次数

可视化大对象堆碎片

是否有任何工具可视化大对象堆?

目前我正在使用ANTS内存分析器,它告诉LOH是碎片但你实际上看不到碎片(我希望看到LOH的可视化表示,如Windows Defrag工具可视化磁盘碎片).

.net memory performance large-object-heap

3
推荐指数
1
解决办法
1401
查看次数

StringBuilder增长超过85k并转向LOH?

可能重复:
StringBuilder的容量如何变化?

假设分配了一个StringBuilder,然后它增长到超过85k,它会被移到大对象堆上吗?

.net clr large-object-heap

1
推荐指数
1
解决办法
553
查看次数

添加到大对象堆的对象

我试图在我们的旧网站中调试 CPU 使用率高的原因,并且通过查看 DebugDiag 中的一些分析,我怀疑 LOH 上的对象数量以及随后的 GC 收集可能是一个原因。在一个 .dbg 文件中,我们在 LOH 上有大约 3.5gb,其中大部分对象是字符串。

我知道要在 LOH 上运行的对象,它们必须超过 85000 字节。

例如,我不确定这是否指的是单个数组。或者它可以引用一个大对象图?

我的意思是,如果我有对象 Foo,它包含 n 个其他对象,每个对象本身包含 n 个对象。如果这些对象中的每一个都包含字符串,并且 Foo(和所有子对象)的总大小大于 85000 字节,那么 Foo 会放在 LOH 上吗?或者,如果在 Foo 对象图中的某个地方有一个大于 85000 字节的数组,它是否只是放在 LOH 上的那个数组?

谢谢。

c# large-object-heap

0
推荐指数
1
解决办法
698
查看次数