2

一部のデータをスクレイピングする VBA マクロ スクリプトがあります。MSIEを使用してスクレイピングしています.MSIEがメモリリークの中心的な問題であると思います。

次のように変数を初期化しています

Set IE = CreateObject("InternetExplorer.Application")

メモリがどのように使用されているかを確認するために、少しテストを行いました。

IE のインスタンスを 1 つだけ作成し、同じ Web サイトに ping を送信するループを作成しました。メモリはリークしていないようです。

次に、常に別のサイトにpingを実行するループを作成し、リクエストごとにメモリ使用量が増加し始めました。

また、反復ごとに新しいオブジェクトを作成し、最後に削除するテストも作成しました(以下に投稿しています)。削除部分が機能していないようです。

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

どんな入力でも素晴らしいでしょう!

4

1 に答える 1

6

上記のコードをテストしたところ、IE オブジェクトが正しく破棄されていました。これに関しても

IE のインスタンスがリクエストをキャッシュしているように見えるため、オブジェクトが大きくなっています。これは単なる仮定です。

はい、時々増加しますが、常にではありません。スクリーンショットを参照してください。

ここに画像の説明を入力

これは 8 ループ用の IE のタスク マネージャーのスクリーンショットです。増加を示していますが、見れば減少しています。したがって、あなたが見ているのはメモリリークではないと思います。

編集

これは、データバンクにあるコードです (私が書いたものではありません) が、実行してメモリ使用量を確認できます。

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

スナップショット

ここに画像の説明を入力

于 2012-07-07T14:20:36.883 に答える