【问题标题】:.NET & CreateObject, whose memory does the COM object use?.NET 和 CreateObject,COM 对象使用谁的内存?
【发布时间】:2013-10-18 11:09:41
【问题描述】:

我有一个 VB.NET 应用程序,它使用 CreateObject 来使用 Excel 并将大量数据转储到其中。我们正在出现内存不足的异常,此时我们的应用程序通常会达到 1GB 的内存。但是我不能把所有的数字加起来。

这是将数据传递到 Excel 的方式:

    worksheet_object.Range("A1").Resize(rows, cols).Value = an_array

应用程序大约 400mb,屏幕上的数据 (datagrid),当它崩溃时,它已经使用了额外的 600mb,尽管带有 CSV 的 Excel 只有 200mb,而 CSV 只有 68mb。我意识到内存中的数组可能会更大一些,但是除非 Excel 以某种方式使用我的应用程序内存,否则 600mb 的数据如何被吞并到 Excel?

我试图通过 CreateObject 找出 Excel 是在它自己的内存空间中运行还是使用我的应用程序的内存空间,完全空白。 ProcessExplorer 将它们显示为单独的进程,所以我不知道该怎么想。

我们发现以 64 位而不是 32 位运行应用程序可以解决问题,但并非我们所有的客户都将拥有 64 位办公室。

所以我的问题是:那一行如何使用 600mb,有没有更好的方法将数据传递到 Excel。

【问题讨论】:

  • Excel 只在自己的进程中分配内存。您需要注意进程中的 GC,并查看它是否经常收集。当您只进行互操作调用时,很容易永远不会触发集合。这可以让 RCW 建立起来。使用 Perfmon.exe 查看 .NET GC 性能计数器,最好使用内存分析器。对策是定期强制 GC,比如每 N 行。
  • 你不说行和列怎么可能? (每个 Excel 单元格可以使用大量内存)。但也许您正在分割可用的 2GB 地址空间:您是否尝试过以较小的块工作?
  • 大约 200,000 行,可能 50 列。被传递的数组有大约 970 万个单元。我找不到获取其内存大小的方法。我想我可以使用二进制序列化程序并将其写入文件。
  • 大概这个操作意味着对数组进行大量的复制。这种大小的工作表占用超过 200MB(假设它的唯一数字):等效的对象数组可能大致相同,然后通过 com-interop 可能意味着内存中至少有一个或 2 个副本。内存碎片可能意味着无法满足对大块连续内存的请求。如果你使用 10 个更小的块,它可能会在 32 位模式下工作

标签: vb.net excel memory com


【解决方案1】:

我敢打赌,这也需要一些时间来运行 1 行,970 万个单元!?但无论如何,两个问题:

1:那一行如何使用 600mb(我假设您的意思是 MB(字节),而不是 mb(位))

我想你用 970 万个细胞回答了这个问题。每个单元只有 61 个字节。我会假设你有一些字符串。每个字符串使用几个字节,单元格中的每个字符加上 2 个字节。带小数点的数字,它们占用 16 个字节.. 句号。更不用说,数组有一些大小来处理它的信息。请参阅此图表以了解数据在 VB 中占用的内容。 2012 VB Data Types 我刚刚学到的一件令人惊奇的事情是因为我太久没有看这张图表了,那就是通过 64 位操作系统,它实际上应该占用更多内存。幸运的是,64 位可以处理更多。

2:有没有更好的方法将数据传递到 Excel。

您可以尝试使用 OLEDB ACE 驱动程序来处理您的 excel 文件。它速度更快,不需要在计算机上安装 EXCEL,有很大的优势。

How To Use ADO.NET to Retrieve and Modify Records in an Excel Workbook With Visual Basic .NET

这篇文章很旧,但仍然相关且非常有帮助。对于较新版本的 excel 的连接字符串,请尝试 ConnectionStrings.com

【讨论】:

  • 我们最终为这个客户端采用了 64 位路由,但我认为这将是一个再次困扰我们的问题,因此这些链接对于查看解决方案应该非常有用。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-13
  • 2010-12-13
  • 2018-06-15
  • 2010-11-06
  • 1970-01-01
相关资源
最近更新 更多