0

スタート メニューのショートカットを追跡するために使用するランチャー ユーティリティを作成しDirectory.GetFiles()ました。Timer

ただし、メモリリークがあります。おかしなことをしているわけではないので、なぜリークしているのかわかりません... プログラムを開いたままにしておくと、数日後には 300MB になりました。CLR プロファイラーを使用してリークを特定しようとしたところ、メモリ リークはStringによって割り当てられたインスタンスから発生しているDirectory.GetFilesと表示され、Directory.GetFileNameWithoutExtension使用しているコードは次のとおりです。

Private Sub tmr_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles tmr.Tick
    IndexStartMenu()
    GC.Collect()
End Sub

Private Sub IndexStartMenu()

    Dim startMenu As IO.DirectoryInfo
    Dim shortcuts() As IO.FileInfo

    'Enumerate current user's start menu
    startMenu = New IO.DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.StartMenu))
    shortcuts = startMenu.GetFiles("*.lnk", IO.SearchOption.AllDirectories)
    For Each lnk As IO.FileInfo In shortcuts
        Dim newRow As DataRow = dtApps.NewRow
        newRow("Application") = IO.Path.GetFileNameWithoutExtension(lnk.FullName)
        newRow("Window") = "Launch"
        newRow("Hwnd") = ""
        newRow("IsShortcut") = True
        newRow("ShortcutPath") = lnk.FullName
        dtApps.LoadDataRow(newRow.ItemArray, LoadOption.Upsert)
        newRow = Nothing
    Next

    'Enumerate all users' start menu
    startMenu = New IO.DirectoryInfo(allUsersStartMenuPath)
    shortcuts = startMenu.GetFiles("*.lnk", IO.SearchOption.AllDirectories)
    For Each lnk As IO.FileInfo In shortcuts
        Dim newRow As DataRow = dtApps.NewRow
        newRow("Application") = IO.Path.GetFileNameWithoutExtension(lnk.FullName)
        newRow("Window") = "Launch"
        newRow("Hwnd") = ""
        newRow("IsShortcut") = True
        newRow("ShortcutPath") = lnk.FullName
        dtApps.LoadDataRow(newRow.ItemArray, LoadOption.Upsert)
        newRow = Nothing
    Next

    'Trying to fix memory usage
    startMenu = Nothing
    Array.Clear(shortcuts, 0, shortcuts.Length)
    shortcuts = Nothing
End Sub
4

1 に答える 1

1

あなたが投稿した方法に基づいて、タイマーは間隔ごとに起動し、それらのディレクトリの内容を繰り返し追加しませんか? dtApps が、アプリケーションの期間中存続するクラスにスコープされた DataTable フィールドである場合、DataTable に行を繰り返し追加するだけで、DataTable が大きくなります。これはメモリ リークではなく、自然な現象です。dtApps の行数を確認します。私の推測では、新しい行のみを追加するつもりです。

また、上記のソリューションを改善し、 FileSystemWatcherを使用してタイマーに基づいて 2 つのディレクトリをポーリングする必要をなくすこともできます。FileSystemWatcher は、ファイル システムに変更があったときにイベントを発生させて通知します。

于 2012-12-21T01:02:54.247 に答える