问题标签 [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.
c# - 大对象堆中的大字符串会导致问题 - 但无论如何它必须以字符串形式结束
我在这里跟进这个问题
我遇到的问题是我有一些来自 MSMQ 的大型对象,主要是字符串。我已将内存问题缩小到在大对象堆 (LOH) 中创建的这些对象,因此将其分段(在分析器的帮助下确认了这一点)。
在我上面发布的问题中,我得到了一些解决方法,主要是将 String 拆分为我所做的 char 数组的形式。
我面临的问题是,在字符串处理结束时(以任何形式),我需要将该字符串发送到另一个我无法控制的系统。所以我正在考虑以下解决方案,将这个字符串放在 LOH 中:
- 将其表示为每个小于 85k 的 char 数组的数组(要放置在 LOH 中的对象的阈值)
- 在发送端压缩它(即在我们这里讨论的接收器系统中接收它之前)并仅在将它传递到第三方系统之前对其进行解压缩。
无论我做什么 - 一种或另一种方式 - 字符串都必须是完整的(没有字符数组或压缩)。
我被困在这里了吗?我在想,如果在这里使用托管环境是一个错误,我们是否应该硬着头皮去使用 C++ 类型的环境。
谢谢, 雅尼斯
编辑:我已将问题范围缩小到此处发布的代码
穿过的大弦被放置在 LOH 中。从收到消息的位置开始,我已经删除了每个处理模块,并且内存消耗趋势保持不变。
所以我想我需要改变这个 WorkContext 在系统之间传递的方式。
c# - 我的对象会被放置在大对象堆中吗?
当 CLR 将对象放在大对象堆上时,是“全有还是全无”的交易?类/结构成员是否“拆分”并放置在不同的堆中?
TwoSmallObjects
由于总大小超过 85,000 字节,是否放置在大对象堆上?即使两个成员都单独低于阈值?怎么样MixedSizeObjects
?
c# - RegEx、StringBuilder 和大对象堆碎片
如何在大字符串中运行大量正则表达式(以查找匹配项)而不会导致 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?
关于这个理论的任何想法?(不幸的是我不能轻易地重现这个问题,我通常会尝试使用内存分析器来观察变化,并且不确定我可以为此编写什么样的隔离测试用例)
.net - 为什么选择大对象堆,我们为什么要关心?
我已阅读有关世代和大型对象堆的信息。但是我仍然不明白拥有大型对象堆的意义(或好处)是什么?
如果 CLR 仅仅依靠第 2 代(考虑到 Gen0 和 Gen1 的阈值很小,无法处理大对象)来存储大对象,会出现什么问题(在性能或内存方面)?
java - 大对象集的Java内存分配
我目前正在使用 Java 开发游戏引擎,但是在堆上分配大量对象时遇到性能问题,例如
由于分配的剪切级别,上面的代码在启动时会遭受大量的帧丢失,我想知道是否有我遗漏的东西或解决这个问题的一些文本。
更新
我的GLParticle类的请求数据成员。
谢谢加里
.net - 64 位系统上的 LOH 碎片有多糟糕
大对象堆碎片在 32 位系统上是一个明显的问题,因为地址空间相对较小,因此您可以用完它并非常“快速”地遇到 OutOfMemoryException
由于 64 位地址空间要大得多,地址用完不是问题(对于我们的场景)。因此,主要问题是这如何影响机器的性能。
LOH 中的可用空间是保留但未提交,还是保持提交?即使它已提交,如果它未使用,它不会被分页并且实际上不占用物理内存吗?
在我们的特定场景中,我们不太担心由于没有足够的地址空间而导致 OOM,因为这将:1. 需要一段时间 2. 当这种情况发生时,我们的服务将自动重新启动。
我们更关心这将对我们运行的机器的整体性能产生影响。
任何人都可以阐明这个问题吗?
java - Java ActiveMQ 发送大对象抛出 EOFException
使用 AciveMQ 发送大型 java 对象时出现 java.io.EOFException。
下面是我要发送的大对象
}
下面是堆栈跟踪。
生产者表明它发送了一个正确的对象。但在消费者方面,它会抛出异常。
我也尝试过使用 ActiveMQConnectionFactory 进行以下配置
请建议我一些解决方案。提前致谢。
jvm - 无法创建启用了 -XX:+UseLargePages 的 JVM
我有一个当前使用 14GB 堆运行的 Java 服务。我很想试试-XX:+UseLargePages选项,看看这会如何影响系统的性能。我已经按照Oracle的描述使用适当的共享内存和页面值配置了操作系统(这些也可以使用在线工具计算)。
配置操作系统后,我可以看到它将预期的内存量分配为大页面。但是,使用选项集启动 VM-XX:+UseLargePages
始终会导致以下错误之一:
当-Xms
/-Xmx
几乎等于巨页分配时:
当-Xms
/-Xmx
小于大页分配时:
我确实尝试过引入一些余地——所以在一个 32GB 的系统上,我分配了 24GB 的共享内存和大页面来与配置有 20GB 堆的 JVM 一起使用,其中当前只有 14GB 被使用。我还验证了执行 JVM 的用户确实具有与/proc/sys/vm/hugetlb_shm_group
.
谁能给我一些关于我可能会出错的地方以及接下来我可以尝试什么的指示?
分配/使用:
-Xms
/-Xmx
- 20GB- 已用堆 - 14GB
/proc/sys/kernel/shmmax
- 25769803776 (24GB)/proc/sys/vm/nr_hugepages
- 12288
环境:
- 系统内存 - 32GB
- 系统页面大小 - 2048KB
- Debian 2.6.26-2-amd64
- Sun JVM 1.6.0_20-b02
解决方案
感谢@jfgagne提供了导致解决方案的答案。除了 /proc/sys/kernel/shmall
设置(指定为 4KB 页面)之外,我还必须按照Thomas 的博客/etc/security/limits.conf
中的描述添加条目。但是,当我的应用程序开始使用时,我还必须复制 root 用户的设置(请注意,限制以 KB 为单位指定):jsvc
还值得一提的是,可以通过使用-version
参数启动 JVM 来快速测试设置:
c# - 使用 Protobuf-net 序列化分块字节数组的内存使用
在我们的应用程序中,我们有一些数据结构,其中包含一个分块的字节列表(当前公开为List<byte[]>
)。我们将字节分块,因为如果我们允许将字节数组放在大对象堆上,那么随着时间的推移,我们会遭受内存碎片的困扰。
我们还开始使用 Protobuf-net 序列化这些结构,使用我们自己生成的序列化 DLL。
然而,我们注意到 Protobuf-net 在序列化时创建了非常大的内存缓冲区。浏览源代码,它似乎可能在整个结构被写入之前无法刷新其内部缓冲区,List<byte[]>
因为它需要在之后将总长度写入缓冲区的前面。
不幸的是,这首先取消了我们对字节进行分块的工作,并最终由于内存碎片给了我们 OutOfMemoryExceptions(异常发生在 Protobuf-net 试图将缓冲区扩展到超过 84k 的时候,这显然把它放在LOH,我们的整体进程内存使用率相当低)。
如果我对 Protobuf-net 工作原理的分析是正确的,有没有办法解决这个问题?
更新
根据马克的回答,这是我尝试过的:
然后序列化它:
ProtoWriter.WriteBytes()
但是,如果我在它调用方法底部的位置放置一个断点DemandSpace()
并进入DemandSpace()
,我可以看到缓冲区没有被刷新,因为writer.flushLock
equals 1
。
如果我像这样为 ABase 创建另一个基类:
然后writer.flushLock
等于。2
_DemandSpace()
我猜我在这里错过了一个与派生类型有关的明显步骤?
.net - C# 中的超大对象和托管堆
当我尝试在物理内存中保存比托管堆大的非常大的对象时会发生什么?例如,一部电影的大小为 4.5 GB,而虚拟内存 (RAM) 的大小仅为 2 GB。在这种情况下垃圾收集器将如何工作?(物理空间足够)