问题标签 [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 投票
3 回答
1335 浏览

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

好的,所以我在 ASP.NET 项目上工作了一段时间,似乎我做出了一些糟糕的设计选择,随着项目在包含的数据方面变得越来越大,这些选择又回来困扰着我。

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

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

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

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

我知道这个问题的说明有些不足。我刚刚意识到我的整体设计可能有缺陷(wrt 可扩展性),我只是想估计到底有多大缺陷。我希望可以收集一些关于标准模式的提示,将其变成一个普遍有用的问题。

0 投票
1 回答
180 浏览

.net - .net 应用程序导致内存碎片

我知道 .NET 应用程序(不使用任何未管理的代码)可能导致内存碎片的唯一方法是大对象堆。有什么方法可以检测您的应用程序是否正在碎片化内存并避免它?

0 投票
2 回答
516 浏览

.net - 从数据库中读取大字符串而不分割大对象堆

我有包含一些相当大的字符串的数据数据库,每个字符串都包含一个序列化的分层数据集合(数据存储为字符串而不是二进制流以允许与 VB6 交互)。据我所知,任何返回超过 85,000 字节字符串的数据库查询都会立即将该字符串扔到大对象堆中。如果字符串立即被分割成更小的部分,因此大对象将是短暂的,有没有办法避免让这些对象进入大对象堆并无用地留在那里直到下一次 LOH 收集?我一直在阅读 LOH 对象应该被重用,但我不知道在这种情况下我将如何去做。

编辑——我将 SqlClient 对象与 DataReader 一起使用。

0 投票
3 回答
2491 浏览

c# - 在大对象堆内存中预分配一些内存

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

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

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

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

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

0 投票
1 回答
152 浏览

.net - 仅使用第 2 代收集大对象堆对象有什么好处?

我知道分代垃圾收集可以提高性能,因为

  1. 在非 Gen2 集合中,任何对象最多必须移动两次,Gen2 集合很少见。
  2. 如果系统正在执行 Gen0 收集,并且自上次 Gen0 收集以来尚未写入对象(Gen1 或 Gen2),则系统不必扫描该对象以标记其中的任何引用(因为它们都将是 Gen1或 Gen2)。同样,如果系统正在执行 Gen1 收集,它可以忽略自上次 Gen1 收集以来未写入的任何对象。由于垃圾收集的大部分工作是扫描对象,因此减少扫描时间是一个很大的胜利。

不过,我很好奇,从 Gen1 垃圾收集中省略大对象会有什么性能优势?大对象即使被垃圾收集器扫描也不会重新定位,我希望 Gen1 集合仍然必须扫描它们的内容,除非或直到两个连续的 Gen1 集合发生而没有干预对象写入。

是否有一些我没有看到的性能优势?

0 投票
2 回答
320 浏览

asp.net-mvc-3 - 为什么大对象堆大多是空的?

为什么.NET 内存管理会创建这么大的对象堆?大部分似乎是空的。这有什么需要担心的吗?

以下数据是否意味着实际上我的应用程序中只有 179 MB 的大型对象?通过从 1171428792 (Heap0 LOH) 中减去 983396616 (free LOH) 得到 179 MB。

以下信息是通过在 w3wp.exe 即 ASP.NET 进程上创建的转储文件上使用 WinDbg 收集的。该进程托管在 Windows 2008 64 位操作系统上。该应用程序是使用 Microsoft .NET Framework 4.0 和 ASP.NET MVC 3 构建的。

0 投票
1 回答
2598 浏览

c# - 处理大字符串,这是大对象堆碎片吗?

我有一个 .NET 3.5 应用程序

  • 一个函数运行一百万次
  • 它在 1MB+ 字符串(不同大小的字符串)中进行搜索、替换和正则表达式操作

当我分析应用程序时,我可以确认这些字符串存储在 LOH 中,但它们稍后也会被 GC 回收,因此在给定时间,其中最多只有 10 个在 LOH 中(10 个线程正在运行)。

我的理解是,这些大字符串位于 LOH 中,然后被 GC 回收,但不知何故由于它们的分配位置(并且在 LOH 中因此没有被压缩),这会导致碎片。尽管操作中没有内存泄漏,但仍会发生这种情况。

它不会在大约 100K 次内引起问题,但是当它达到 1M+ 时,它会出现内存不足的异常。

我正在使用 ANTS Memory Profiler,这是我在早期执行中得到的结果:

  1. 根据手头的数据,你认为我的诊断是正确的吗?
  2. 如果是这样,我该如何解决这个 LOH 碎片问题?我必须处理这些字符串,它们是大字符串。我应该找到一种方法将它们分开并像这样处理吗?在这种情况下,在拆分字符串中运行正则表达式等将非常具有挑战性。
0 投票
1 回答
1510 浏览

.net - 可视化大对象堆碎片

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

目前我正在使用 ANTS Memory Profiler,它告诉 LOH 是碎片化的,但您实际上看不到碎片(我希望看到 LOH 的可视化表示,如 Windows Defrag 工具可视化磁盘碎片)。

0 投票
2 回答
608 浏览

.net - StringBuilder 增长超过 85k 并转移到 LOH?

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

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

0 投票
4 回答
3138 浏览

c# - 来自队列的大对象堆和字符串对象

我有一个 Windows 控制台应用程序,它应该可以运行数天和数月而无需重新启动。该应用程序从 MSMQ 检索“工作”并对其进行处理。有 30 个线程同时处理一个工作块。

来自 MSMQ 的每个工作块大约为 200kb,其中大部分分配在单个 String 对象中。

我注意到在处理了大约 3-4 千个这样的工作块之后,应用程序的内存消耗非常高,消耗了 1 - 1.5 gb 的内存。

我通过分析器运行应用程序并注意到大部分内存(可能是 gig 左右)在大型对象堆中未使用,但结构是碎片化的。

我发现这些未使用的(垃圾收集的)字节中有 90% 是以前分配的字符串。那时我开始怀疑来自 MSMQ 的字符串被分配、使用然后解除分配,因此是碎片的原因。

我知道像 GC.Collect(2 or GC.Max...) 这样的东西不会有帮助,因为它们 gc 大对象堆但不压缩它(这是这里的问题)。所以我认为我需要缓存这些字符串并以某种方式重新使用它们,但由于字符串是不可变的,我将不得不使用 StringBuilders。

我的问题是:无论如何不改变底层结构(即使用MSMQ,因为这是我无法改变的)并且仍然避免每次都初始化一个新的字符串以避免分割LOH?

谢谢, 雅尼斯

更新:关于当前如何检索这些“工作”块

目前,这些在 MSMQ 中存储为 WorkChunk 对象。这些对象中的每一个都包含一个名为 Contents 的字符串和另一个名为 Headers 的字符串。这些是实际的文本数据。如果需要,我可以将存储结构更改为其他内容,如果需要,我可以将底层存储机制更改为 MSMQ 以外的其他内容。

目前我们在工作节点方面

WorkChunk 块 = _Queue.Receive();

所以在这个阶段我们可以缓存的东西很少。如果我们以某种方式改变结构,那么我想我们可以取得一些进展。无论如何,我们都必须解决这个问题,所以我们将尽一切可能避免浪费数月的工作。

更新:我继续尝试以下一些建议,并注意到无法在我的本地计算机上重现此问题(运行 Windows 7 x64 和 64 位应用程序)。这让事情变得更加困难 - 如果有人知道为什么,那么它真的会帮助在本地重新解决这个问题。