2012-07-07 147 views
1

我有擦伤一些数据的VBA宏脚本。使用MSIE它 它的擦伤。我相信MSIE是核心问题的内存泄漏。VBA宏内存泄漏(如何清除变量=

我“M初始化变量等

Set IE = CreateObject("InternetExplorer.Application") 

我了一个小测试,看看是如何被使用的存储器。

我制成的环,这使得只有1 IE的实例和坪同一个网站。 内存似乎不韭菜。

然后,我做了一个循环,总是ping不同的网站和内存使用量开始增加与每个请求。

我还做了一个测试(我在下面发布),它在每次迭代中创建NEW对象并在最后删除它。删除部分似乎不起作用。

看来IE的实例正在缓存请求,因此对象变得越来越大。 这只是一个假设。

下面是我用来测试泄漏的示例代码。

Do While True 
    Dim IE As Object 
    Set IE = CreateObject("InternetExplorer.Application") 

    IE.Navigate "https://www.google.hr/#hl=hr&gs_nf=1&cp=3&gs_id=8&xhr=t&q=" & Counter 
    IE.Visible = True 

    Do While IE.readyState <> 4 Or IE.Busy = True 
     Application.Wait Now() + TimeValue("00:00:01") 
     DoEvents 
    Loop 

    Application.Wait Now() + TimeValue("00:00:01") 
    Counter = Counter + 1 
    Range("A" & Counter).Value = "https://www.google.hr/#hl=hr&gs_nf=1&cp=3&gs_id=8&xhr=t&q=" & Counter 

    IE.Quit 
    Set IE = Nothing 
Loop 

任何投入将是巨大的!

+0

我测试上面的代码中,IE实例是越来越正确销毁? – 2012-07-07 13:58:05

+0

当你将一个对象设置为空或者它实际上被破坏时可能会有延迟... – 2012-07-07 18:39:18

+0

IE和其他Web浏览器总是将先前的页面保留在内存中,这样当你使用后退按钮时,页面立即显示出来。这是设计。 – Tmdean 2012-07-07 22:18:05

回答

6

我测试了上面的代码,它正确销毁IE对象。同样在这方面

看来,IE的实例缓存请求,使对象变得越来越大。这只是一个假设。

是的,它有时会增加它,但并不总是。看截图。

enter image description here

这是任务管理器的IE浏览器的截图为8环。它显示增加,但如果你看到它也会降低。所以我相信你所看到的不是内存泄漏。

编辑

下面是一些代码,我在我的数据库有(我没有写它),但你可以运行它来检查内存使用情况。

Sub Sample() 
    Do While True 
     Dim IE As Object 
     Set IE = CreateObject("InternetExplorer.Application") 

     IE.Navigate "https://www.google.hr/#hl=hr&gs_nf=1&cp=3&gs_id=8&xhr=t&q=" & Counter 
     IE.Visible = False 

     Debug.Print GetProcessMemory("iexplore.exe") 

     Do While IE.readyState <> 4 Or IE.Busy = True 
      Application.Wait Now() + TimeValue("00:00:01") 
      DoEvents 
     Loop 

     Application.Wait Now() + TimeValue("00:00:01") 
     Counter = Counter + 1 
     Range("A" & Counter).value = "https://www.google.hr/#hl=hr&gs_nf=1&cp=3&gs_id=8&xhr=t&q=" & Counter 

     IE.Quit 
     Set IE = Nothing 
    Loop 
End Sub 

Private Function GetProcessMemory(ByVal app_name As String) As String 
    Dim Process As Object, dMemory As Double 

    For Each Process In GetObject("winmgmts:"). _ 
    ExecQuery("Select WorkingSetSize from Win32_Process Where Name = '" & app_name & "'") 
     dMemory = Process.WorkingSetSize 
    Next 
    If dMemory > 0 Then 
     GetProcessMemory = ResizeKb(dMemory) 
    Else 
     GetProcessMemory = "0 Bytes" 
    End If 
End Function 

Private Function ResizeKb(ByVal b As Double) As String 
    Dim bSize(8) As String, i As Integer 
    bSize(0) = "Bytes" 
    bSize(1) = "KB" 'Kilobytes 
    bSize(2) = "MB" 'Megabytes 
    bSize(3) = "GB" 'Gigabytes 
    bSize(4) = "TB" 'Terabytes 
    bSize(5) = "PB" 'Petabytes 
    bSize(6) = "EB" 'Exabytes 
    bSize(7) = "ZB" 'Zettabytes 
    bSize(8) = "YB" 'Yottabytes 
    For i = UBound(bSize) To 0 Step -1 
     If b >= (1024^i) Then 
      ResizeKb = ThreeNonZeroDigits(b/(1024^_ 
       i)) & " " & bSize(i) 
      Exit For 
     End If 
    Next 
End Function 

Private Function ThreeNonZeroDigits(ByVal value As Double) As Double 
    If value >= 100 Then 
     ThreeNonZeroDigits = FormatNumber(value) 
    ElseIf value >= 10 Then 
     ThreeNonZeroDigits = FormatNumber(value, 1) 
    Else 
     ThreeNonZeroDigits = FormatNumber(value, 2) 
    End If 
End Function 

快照

enter image description here

+0

+1像往常一样漂亮! – 2012-07-08 00:07:47

+0

为了记录,我有一个非常类似的过程,我在IE和Excel之间使用。内存在运行时总是很高,但在完成后它会下降。所以,根据我的经验 - 不如Sid的令人敬畏的编码技巧,我不认为这会泄漏记忆。 – Gaffi 2012-07-09 15:27:37