【发布时间】:2018-09-19 17:19:26
【问题描述】:
以下简单代码将一些单元格复制到剪贴板并将其作为文本数据取回。稍后此数据将被发布到内部网络服务,但此时已将其注释掉。 每次我运行脚本时,Excel 的已用内存都会增加大约 80MB(字符串大小的两倍)。我不知道垃圾收集器在哪里/为什么失败以及我能做些什么。
Sub memory_leak()
Dim DataObj As New MSForms.DataObject
Dim data As String
'Copy Data Range ~ the first 250.000 rows / 22 columns
Range(Cells(9, 1), Cells(250000, 22)).Copy
DataObj.GetFromClipboard
data = DataObj.GetText
' Call postToURL("http://intranet/API.php?action=test", data)
'Try to free memory...
Application.CutCopyMode = False
DataObj.Clear
data = ""
End Sub
【问题讨论】:
-
将它发送到剪贴板并执行
.GetText有什么意义?为什么不直接使用Range(...).Values? -
Dim .... As New正在声明一个自动实例化的对象,这意味着DataObj不能真正被销毁(尝试Set DataObj = Nothing然后Debug.Print DataObj Is Nothing)。我会从Set在单独的指令中开始。 -
@BruceWayne:
Range..Values给出了一个 2D 数组,这几乎是不可能使用的,然后试图从中创建一个字符串。在循环结构时,我所有的尝试都会导致非常(非常)大的运行时间。而Join仅适用于一维数组。 -
@MathieuGuindon:有趣的一点。 “将其设置在单独的指令上”到底是什么意思?我只是试图在全局范围内调暗 DataObj 以强制重用,但这会导致另一个错误(DataObject:GetText Data in clipboard is invalid)
-
VBA 不是垃圾收集的,它是引用计数的。请注意,
Dim语句是不可执行的(您不能在它们上放置断点),但Set语句是可执行的。所以Dim DataObj As MSForms.DataObject和下一行Set DataObj = New MSForms.DataObject就是我的意思。也就是说问题可能出在其他地方,但Dim ..As New不可能有帮助。