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

2024-01-17

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

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

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

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

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

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

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

谢谢, 雅尼斯

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

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

目前我们在工作节点方面做

WorkChunk 块 = _Queue.Receive();

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

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


您的问题似乎是由于大对象堆上的内存分配造成的 - 大对象堆未压缩,因此可能是碎片的来源。这里有一篇很好的文章,其中更详细地介绍了一些调试步骤,您可以按照这些步骤来确认大对象堆的碎片正在发生:

大型对象堆被发现 http://msdn.microsoft.com/en-us/magazine/cc534993.aspx

您似乎有两个三个解决方案:

  1. 更改您的应用程序以对块/较短的字符串执行处理,其中每个块小于 85,000 字节 - 这可以避免分配大对象。
  2. 更改您的应用程序以预先分配一些大内存块,然后通过将新消息复制到分配的内存中来重新使用这些块。看使用字节数组时的堆碎片 https://stackoverflow.com/questions/5696377/heap-fragmentation-when-using-byte-arrays.
  3. 保持原样 - 只要您没有遇到内存不足的异常,并且应用程序不会干扰系统上运行的其他应用程序,您就应该保持原样。

这里了解虚拟内存和物理内存之间的区别很重要 - 即使进程使用大量虚拟内存,如果分配的对象数量相对较低,那么该进程的物理内存使用率也较低(未使用的内存被分页到磁盘)这意味着对系统上其他进程的影响很小。您可能还会发现“VM Hoarding”选项有帮助 - 请阅读“Large Object Heap Uncovered”文章以获取更多信息。

任何一种更改都涉及更改您的应用程序以使用字节数组和短子字符串而不是单个大字符串来执行部分或全部处理 - 这对您来说有多困难将取决于您正在执行的处理类型。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

来自队列的大对象堆和字符串对象 的相关文章

随机推荐

  • Jetpack Compose 折叠工具栏

    我找不到关于此事的任何文件 是否有类似的内容CollapsingToolbar在撰写中 我发现的只是提及它here https developer android com jetpack compose gestures 但没有说明如何设置
  • 如何向 selenium chrome webdriver 添加多个扩展

    如何向 selenium chrome webdriver 添加多个扩展 我尝试使用逗号添加扩展名 但出现错误 chrome options add extension r C Users Administrator Desktop chr
  • Python:每三个单词分割字符串

    我已经搜索了一段时间 但似乎找不到这个小问题的答案 我有这段代码 应该在每三个单词后分割字符串 import re def splitTextToTriplet Text x re split S s 2 S Text return x p
  • 如何在 C 中通过 tcp 套接字构建协议标头和正文

    我正在写一个 tacacs 客户端 我正在尝试编写一个简单的数据包发送到服务器 我检查了RFC 页面 https datatracker ietf org doc html draft grant tacacs 02我看到协议需要在每个数据
  • 在 mamp 上运行 php [关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 我已经在我的 macbook pro 中安装了 MAMP 我想运行一个 php ini我能做些什么 Applications MAMP ht
  • Scala - 从 ISO-8859-1 转换为 UTF-8 会导致外来字符陌生

    这是我的问题 我有一个已转换为字节数组的输入流 但我不知道运行时输入流的字符集 我最初的想法是用 UTF 8 进行所有操作 但我发现编码为 ISO 8859 1 且包含外来字符的流存在奇怪的问题 那些疯狂的瑞典人 这是有问题的代码 IOUt
  • 配置项目“:app”时出现问题。在react-native中并给出一些字节代码作为错误

    当我运行react native应用程序时创建项目后 它给了我这个错误 FAILURE Build failed with an exception What went wrong A problem occurred configurin
  • 更改字符串的排序顺序,包括特殊字符(例如“_”)

    PHP 脚本按降序输出电子邮件地址列表 如下所示 email protected cdn cgi l email protection email protected cdn cgi l email protection email pro
  • 如何使用 Java / Scala 在内存中保存数据结构 G-wan

    我将 Gwan 视为运行 Scala 应用程序的更高性能方式 我们的用例涉及使用 Scala 数据结构在内存中保存大量数据 这比简单的哈希图要复杂一些 因此我希望避免尝试将其插入 Gwan 附带的 K V 存储中 此外 还有许多非常适合交互
  • VS 2013 看不到我的自定义签入策略

    我有通过 VSIX 部署的自定义签入策略 现在我尝试在 Visual Studio 2013 中使用它们 我做了什么 我在 VS 2013 中打开了我的策略 将 vsixmanifest 中的 安装目标 更改为 10 0 13 0 然后构建
  • Azure Devops yaml 部署管道显示不需要的消息/描述

    最近 我从传统的图形部署管道迁移到可重用的 yaml 构建和部署管道 yaml 构建管道正在交付在部署管道中使用的 多个 工件 运行部署管道 使用参数和设置 yaml 模板等时 我看到 当管道完成后 会有如下描述 由于部署管道与构建管道不在
  • 集成测试中访问内存dbcontext

    如何在集成测试中访问内存数据库的 dbcontext 我已经按照这里的代码进行操作 https learn microsoft com en us aspnet core test integration tests view aspnet
  • 将现有表上的 newid() 更改为 newsequentialid()

    目前 我们有许多表在主键上使用 newid 这导致了大量的碎片 所以我想更改该列以使用 newsequentialid 代替 我认为现有数据仍将保持相当分散 但新数据的分散程度将减少 这意味着我也许应该等待一段时间 然后再将 PK 索引从非
  • 如何从基类的实例创建派生类的实例并包含私有字段?

    我的问题有点与这个问题 https stackoverflow com questions 25163478 create an instance of derived class from the base class但更具体一点 我有一
  • Hibernate 的 org.hibernate.hql.ast.QuerySyntaxException

    我刚开始使用 Hibernate 和 Java 我收到以下异常 我在网上找到的有关此错误的内容似乎没有帮助 有任何想法吗 例外情况 java lang IllegalArgumentException org hibernate hql a
  • 从 DB2 转储 SQL

    我正在尝试将一台 IBM DB2 UDB 服务器中特定模式的内容转储到 sql 文本文件中 很像 mysql 的 mysqldump 功能 我遇到了 db2look 但它只转储模式的结构 只有 ddl 没有 dml 那么我怎样才能完成我的事
  • 从连接列创建虚拟矩阵[重复]

    这个问题在这里已经有答案了 我正在使用 R 并且我有一个如下所示的列 relative aunt mother grandmother sister mother 我想要的结果应该是这样的 mother sister aunt grandm
  • InstanceDouble(session) (匿名)> 收到意外消息 :[]= with

    我对 rspec 行为有疑问 我尝试为我使用的服务编写测试session 用于读取一些值并覆盖该值 例如我想测试什么 class CurrentCartService attr reader user session def initial
  • Android:CollapsingToolbarLayout 中的 MapView

    我目前正在尝试放置一个Map View 或包含地图的片段 内CollapsingToolbarLayout 我想在它上有视差效果RecyclerView卷轴 不幸的是 它根本没有出现 连灰色网格都没有 不过 折叠动画正在发挥作用 我到处寻找
  • 来自队列的大对象堆和字符串对象

    我有一个 Windows 控制台应用程序 应该可以运行数天和数月而无需重新启动 该应用程序从 MSMQ 检索 工作 并对其进行处理 有 30 个线程同时处理一个工作块 来自 MSMQ 的每个工作块大约为 200kb 其中大部分分配在单个 S