MemoryStream使用导致内存不足异常

2023-11-24

我在多次使用 MemoryStream 时遇到问题。

Example:

For Each XImage As XImage In pdfDocument.Pages(pageCount).Resources.Images
   Dim imageStream As New MemoryStream()
   XImage.Save(imageStream, System.Drawing.Imaging.ImageFormat.Jpeg)

   ' some further processing

   imageStream.Close()
   imageStream.Dispose()    
Next

这段代码循环浏览 PDF 文件页面上的图像。该文件最多可能有 cca​​ 500 页,假设每页有 5 个图像。它会导致数千次迭代。问题是 MemoryStream 未释放,导致内存不足异常。 XImage 通常约为 250 kB。

我在这里使用 Aspose.PDF 库来处理 PDF(XImage 是该库中的一个类),但这并不重要。我尝试制作一个简单的示例,其中我只是创建一个新的 MemoryStream 并向其中保存一个虚拟位图。它会导致同样的问题。

我还尝试使用 FileStream 而不是 MemoryStream,但其行为相同。

任何帮助表示赞赏。

Thanks

Jiri


流中的内存被释放。我答应你。确实如此。

没有被释放的是地址空间在您的应用程序中以前被该内存占用。您的计算机有足够的内存可用,但您的特定应用程序崩溃了,因为它无法在地址表中找到可以分配更多内存的位置。

达到限制的原因是 MemoryStream 在增长时会回收其缓冲区。它内部使用 byte[] 来保存其数据,并且默认情况下将数组初始化为一定的大小。当您写入流时,如果超出数组的大小,流将使用加倍算法来分配新数组。然后信息从旧数组复制到新数组。此后,旧数组可以并且将会被收集,但它不会被压缩(认为​​:碎片整理)。结果是程序的虚拟地址表中出现了漏洞,这些漏洞对于 MemoryStream 缓冲区而言不再足够大。一个 MemoryStream 可能使用多个数组,从而导致多个内存漏洞,其总地址空间可能比源数据大得多。

AFAIK,目前无法强制垃圾收集器压缩内存地址空间。因此,解决方案是分配一个可以处理最大图像的大块,然后一遍又一遍地重复使用同一块,这样您就不会得到无法到达的内存地址。

对于此代码,这意味着在循环外部创建 MemoryStream,并将整数传递给构造函数,以便将其初始化为合理的字节数。您会发现这也给您带来了很好的性能提升,因为您的应用程序突然不再花时间频繁地将数据从一个字节数组复制到另一个字节数组,这意味着即使您可以压缩地址表,这也是更好的选择:

Using imageStream As New MemoryStream(307200) 'start at 300K... gives you some breathing room for larger images
    For Each XImage As XImage In pdfDocument.Pages(pageCount).Resources.Images

       'reset the stream, but keep using the same memory
       imageStream.Seek(0, SeekOrigin.Begin)
       imageStream.SetLength(0)

       XImage.Save(imageStream, System.Drawing.Imaging.ImageFormat.Jpeg)

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

MemoryStream使用导致内存不足异常 的相关文章

  • 为什么必须在 C# 中 Close() 文件?

    我知道这可能看起来很愚蠢 但为什么以下代码仅在我 Close 文件时才有效 如果我不关闭文件 则不会写入整个流 Steps 在表单加载时运行此代码 显示后使用鼠标关闭表单 程序终止 当文件对象超出范围时 不应该自动刷新或关闭吗 我是 C 新
  • 为什么 F# 的默认集合是排序的,而 C# 的不是?

    当从 C 世界迁移到 F 最惯用的可能 思维方式时 我发现了这个有趣的差异 在 C 的 OOP mutable 世界中 默认的集合集合似乎是HashSet https learn microsoft com en us dotnet api
  • 单元测试验证失败

    我正在运行我的单元测试PostMyModel路线 然而 在PostMyModel 我用的是线Validate
  • vb.net:查找字符串中字符串的位置?

    vb net 中是否使用 instr 来实现此目的 使用 String IndexOf http msdn microsoft com en us library system string indexof aspx http msdn m
  • 如何更改字体的元数据(特别是标题)?

    我需要一种动态更改字体名称的方法 但在 net 中找不到这样做的方法 我不关心字体文件类型 所以otf fon ttf都打开 我尝试过的事情 使用 dsofile dll OleDocument 属性读取器 这些与访问字体名称的任何内容所使
  • MVC 5 中的“缓存配置文件”

    我是 MVC 的初学者 我有一个项目要从 MVC2 转换到最新版本的 MVC 我读了一些关于MVC 4的书 所以我开始了解主要机制 但是 在转换我的 MVC 2 解决方案时 我遇到了一个属性问题 OutputCache 例如 我有多个这样的
  • string.IsNullOrEmpty() 与 string.NotNullOrEmpty()

    我很好奇是否有开发人员更频繁地使用 string IsNullOrEmpty 来表示负数而不是正数 e g if string IsNullOrEmpty 我99 的时间都是这样使用这个方法的 对此的设计决定是什么 因为 IsNullOrE
  • VB.NET 和 MySql UPDATE 查询

    我的代码在这里没有错误 至少在我调试它时没有错误 我使用VS 2010 但我希望发生的是 当我单击添加按钮时 文本框 txtQty 中的数字将添加到当前保存在 数量 列中的数字中 例如 txtQty 100 该列上的当前值为 200 我想将
  • 循环内声明的变量在循环的每次迭代中保持值

    我无法确定这是一个错误还是一个功能 For i 0 To 4 Dim strTest As String If i 0 Then strTest test value End If Console WriteLine strTest Nex
  • System.IO.FileInfo 的“目标”成员记录在哪里?

    PowerShell 命令行开关Get Item 如果应用于文件 则返回System IO FileInfo type PS C gt item get item c windows System32 atl dll PS C gt ite
  • 正则表达式替换,但仅限于两种模式之间

    好的 我有一个多行字符串 我正在尝试对其进行一些清理 每行可能是也可能不是一大段引用文本的一部分 例子 This line is not quoted This part of the line is not quoted but this
  • 本机线程异常会毫无例外地导致 .Net 应用程序崩溃

    我发现了一种情况 我的 Net 应用程序会意外崩溃 而不会引发任何异常 我希望 至少 AppDomain UnhandledException在这种情况下工作 以便至少使我能够记录错误并向用户提供一些信息 在这种情况下 我有一个 Net 程
  • 在 .NET 中旋转 JPEG,质量损失最小

    我正在尝试支持从 ASP NET MVC 旋转 JPEG 图像 以 90 度增量 我正在尝试使用System Drawing GDI 但是我遇到了问题 我尝试使用Image RotateFlip http msdn microsoft co
  • 比较 LINQ to SQL 中的两个日期

    我有一个数据库 其中有一个名为会议的表 会议日期使用以下格式存储在此表中 May 2nd 2011 例如 格式为5 2 2011 我的要求是获取两个日期 例如 2011 年 4 月 25 日和 2011 年 5 月 2 日 之间的会议 并编
  • 如何使用 ProtoGen 从 proto 文件生成结构

    我们一直在使用 protobuf net ProtoGen 从 proto 文件生成 C cs 文件 我们希望代替类来生成结构 例如 DataContract public struct Entity1 ProtoMember 1 publ
  • .NET - 将颜色名称字符串转换为 System.Drawing.Color

    将 red green yellow aliceblue 等字符串转换为实际的 System Drawing Color 值的最佳方法是什么 我正在查看反思 发现有些事情似乎不对劲 您可以使用 Color FromName
  • 为什么我无法调试动态加载的程序集?

    我正在开发一个 Web API 项目 该项目使用内部模拟框架 允许拦截和修改来自控制器的响应 它使用 MEF 加载包含某些先决条件匹配时执行的代码的程序集 我知道这是正常工作的 因为我可以在响应中看到模拟已被执行 但由于某种原因我无法调试动
  • 使用非字符串作为字符串(而不是自动使用 ToString)时如何显示错误?

    建议的重复确实是一个类似的问题 然而 答案只涵盖一种选择 禁用 ToString 本身 还有其他可能的解决方案 例如让 Visual Studio 警告我 或者不调用 ToString 仔细阅读那里的答案 他认为is调用 只是解释说没有办法
  • 如何组合||条件语句中的运算符[重复]

    这个问题在这里已经有答案了 代替 if foo 1 foo 5 foo 9 我喜欢将它们组合起来 类似于以下内容 这不起作用 if foo 1 5 9 那可能吗 不幸的是不是 你最好的选择是创建一个扩展方法 public static bo
  • Gridview 错误:对 Bind 的调用格式不正确

    我有以下 gridview 代码

随机推荐