问题标签 [large-object-heap]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
291 浏览

.net - 由于固定对象,.NET LOH 上的碎片

我正在对使用 .net 4.5 Asp.net + Unity 3.0.1304.1 + Nhibernate 3.3.1.4 编写的应用程序进行故障排除,该应用程序的内存消耗达到 3 到 5 GB,高于预期。

在收集了一些内存转储后,很明显大对象堆上有碎片。

我的第一个想法是将应用程序更新到 .net 4.5.1 并告诉 GC 压缩 LOH,但我注意到固定对象数组的数量,这导致了一个演示应用程序可以得出结论,堆压缩不是在固定对象场景中很有帮助,并且在没有固定对象时甚至没有必要,因为没有碎片。

所以我试图跟踪这个固定的对象并遇到了这个问题,据说静态成员负责那些固定的对象并且句柄位于高频堆上。

我的问题是:

  • 我该如何继续尝试解决碎片问题?
  • 由于我从 WinDbg 知道的命令不起作用,如何获得有关高频堆的更多信息?

以上来自windbg的一些打印:

0 投票
1 回答
1637 浏览

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

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

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

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

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

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

procdump -ma psid

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

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

我一直在考虑的可能解释:

  • LOH 并没有真正被完全压缩
  • 超出分析器显示的对象使用了一些内存
0 投票
1 回答
65 浏览

.net - 大对象堆压缩的默认策略

默认情况下,.NET 框架用于压缩大对象堆的策略是什么?

  • 从不压实
  • 一段时间后压缩(不像分代堆那样积极)

什么持有?如果“一段时间后”,是否有一些关于“多久”或“何时”的细节?

(我对高于 4.5 的 .NET 框架版本感兴趣)

0 投票
1 回答
120 浏览

vb.net - 在 vb.net 中管理 LOH

我有一个 vb.net 应用程序分发给我的分析师——我们一次可能分配 100 个 200MB 图像。该应用程序使用 GDI+ 依次打开大 jpg 图像,并将图像放置在 LOH 中。我扫描每个像素寻找数据。- 完成后,我处理图像并使用 GC.collect。但这并不能清除 LOH,因此 LOH 会不断增加,直到应用程序崩溃。一种解决方法是将任务分成 25 个实例块,但这很冒险,因为我们的分析师经常在深夜这样做——也许在喝一两杯啤酒之后。

C# 构造是

但在 vb.net 中没有可用的 GCSettings

我的 vb.net 代码是

但我找不到强制 LOH 压缩的 vb.net 方法

完成后

你能帮我吗?

0 投票
1 回答
449 浏览

c# - C# 内存问题

我有一个应用程序:

  • 针对 C# 6
  • 目标.net 4.5.2
  • 是 Windows 窗体应用程序
  • 在 AnyCPU 模式下构建,因为它...
  • 利用无法升级到 64 位、非托管内存的旧 32 位库
  • 使用第三方控件供应商 DevExpress
  • 每天处理数 GB 的数据以生成报告

在具有许多绘图的作业中使用几个小时后,应用程序最终会耗尽内存。根据性能计数器,我花了很长时间清理代码中发现的许多泄漏,并且已经使项目处于最坏的情况下,它可能在任何给定时间使用超过 400,000K 的内存。由于数据是在锯齿状数组中处理的,因此处理此数据目前没有产生任何问题,从而防止了大对象堆的任何问题。

上次发生这种情况时,用户使用了大约 305,000K 的内存。该应用程序是如此“内存不足”,以至于错误对话框甚至无法在出现的 MessageBox 中绘制错误图标,该图标通常所在的空间全是黑色的。

到目前为止,我已经完成了以下工作来清理它:

  • Windows 窗体利用 Disposed 事件来确保清理资源,需要时手动调用 dispose
  • 业务对象利用 IDisposable 删除引用
  • 使用 ANTS 内存分析器和 SciTech 内存分析器验证清理。低内存使用表明情况并非如此,但我想看看我是否看到任何可能有帮助的东西,我不能
  • 利用 GCSettings.LargeObjectHeapCompactionMode 属性从处理大对象堆 (LoH) 中可能碎片的数据中删除任何碎片

几乎每一篇我曾经到过这一点的文章都表明内存不足实际上意味着连续的地址空间不足,并且考虑到正在使用的数量,我同意这一点。我不确定此时该做什么,因为据我了解(并且可能非常错误)是垃圾收集器会在进程进行时清除它以腾出空间,除了 LoH,它是现在使用 .net 4.5.1 中引入的新 LargeObejctHeapCompactionMode 属性手动清理。

我在这里想念什么?我无法构建到 64 位,因为旧的 32 位库包含我们无法访问的专有算法,甚至梦想生产 64 位版本。我应该使用这些配置文件中的任何模式来准确识别这里失控的情况吗?

如果这个地址空间不能被清除,这是否意味着所有的 c# 应用程序最终都会因此而运行“内存不足”?

0 投票
0 回答
186 浏览

c# - 如果大对象堆中的一个对象引用了小对象,这是否应该防止它们在第 2 代 GC 之前被垃圾收集?

我在 Windows x64 上运行的 .NET Core 2.1 应用程序分配大型结构数组,每个结构在字段中保存一个类。数组最终位于大对象堆上,因此直到完整(第 2 代)GC 才会收集它们。这是意料之中的。让我有点吃惊的是,结构引用的类似乎在第 2 代 GC 之前也不会被 GC。这是预期的行为吗?

如果我也有一个大的 HashSet,就会发生类似的事情,因为 HashSet 在内部保留了一个 HashSet.Slot 数组 - 一个结构。

一些重现问题的代码:

当我在 64 位系统上使用包含 11,000 个元素的数组运行此程序时(因此它超过了 LOH 的 85KB 阈值),MyClass 的终结器不会运行。输出:

他们运行 10,000 个元素。我想我希望运行时 GC MyClass 因为它无法访问,即使它仍然被另一个无法访问的对象引用。这是它应该如何工作的吗?

0 投票
0 回答
30 浏览

garbage-collection - CLR Profiler LOH 大小与按地址 LOH 大小的对象不匹配?

我正在使用 CLR 分析器检查我的程序的内存使用情况,并且我关心 LOH 分配。基本上,我将 10 个大小为 1 mb 的文件并行分配给 Azure 数据湖服务文件(使用 concurrentAppend API)。理论上,LOH 大小应该是 10 mb,对吧?在报告预览中(图片 1)-> 我看到 LOH 堆字节为 3.195 MB。当我按地址检查对象时(图 2)-> LOH 分配正好 10 MB(我通过在 LOH 栏上运行光标进行检查,发现 10 个地址,每个地址都有 1 mb system.byte[] 数据。

那么为什么我在预览报告中得到 3.199 MB?

CLR 探查器报告预览

按地址窗口的对象

0 投票
1 回答
52 浏览

c# - GC.CollectionCount 是否只分析分代堆?C# .netcore

GC.CollectionCount 的 MSDN 文档指出:“返回指定代对象的垃圾收集发生的次数。”

这是否意味着它只在分代堆上执行此分析,或者是否有某种方法可以测量大对象堆中发生的集合数量?

0 投票
1 回答
184 浏览

c# - C# - 可以将字符串存储在大对象堆 (LOH) 中吗?

最近在面试中被问到,C#中的字符串能不能来LOH。面试官提到GC逻辑有一些优化,将单个大字符串拆分成几个较小的字符串,所以这个字符串永远不会到达LOH。

我没有在 MSDN 文章中找到相关信息: https  ://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/large-object-heap和  https://docs.microsoft.com/ en-us/archive/msdn-magazine/2008/june/clr-inside-out-large-object-heap-uncovered

那么在 CLR 中是否有关于在 LOH 中存储字符串的任何含义或优化?它是否与字符串实习有关?

0 投票
1 回答
60 浏览

c# - 即使不超过 85,000 字节,是否可以将对象强制到大对象堆 (LOH) 上?

我有一种情况,我分配了大量内存,但在许多较小的子阵列中。我注意到,一旦我通过每个数组大约 85,000 字节的阈值,性能就会明显变差。我假设性能下降是因为较小的数组被分配在“小对象堆”(SOH)而不是“大对象堆”(LOH)上。

# 数组 每个数组的大小(字节) 分配时间
1,154 532,480 377毫秒
1,319 465,920 412毫秒
1,539 339,360 439 毫秒
1,847 332,800 435毫秒
2,308 266,240 446毫秒
3,077 199,680 491毫秒
4,616 133,120 514毫秒
9,231 66,560 4420毫秒

请注意,在所有情况下,分配的总内存约为586MB,但在最后一种情况下,分配的时间要长一个数量级。

快速解决此性能问题的第一个想法是以某种方式告诉 C# 运行时我想要大型对象堆中的这些数组,即使它们小于阈值。我认为这将使分配时间与其他情况一致。

但是,我似乎无法找到是否有办法做到这一点。看起来以前没有人想要一个对象进入大对象堆。所以,我问:是否有可能以某种方式标记这些数组以强制它们进入大对象堆,即使它们小于 85,000 字节的阈值?

(将 85,000 字节阈值降低到 65,000 字节的方法也可以解决我的问题,但我也找不到解决方法!)