【入門編】VB.NETアプリケーションのメモリリーク検出と対策:WinDbgとdotMemoryを用いたアンマネージド・マネージド資源の解析手法 – Visual Basic (VB / VB.NET)解析バイブル

スポンサーリンク

VB.NETの「見えないメモリリーク」を制する:伝説のデバッグ作法

こんにちは。長年、数多の基幹システムをVB.NETで支えてきたエンジニアです。

「プログラムを動かし続けると、なぜかPCが重くなる」「長時間稼働させると落ちる」。そんな悩みを抱えていませんか?
VB.NETはガベージコレクション(GC)が自動でメモリを管理してくれますが、「自動だから何もしなくていい」というのは大きな誤解です。特に、業務アプリでありがちな「イベントハンドラの解除忘れ」や「アンマネージド資源の放置」は、リークの典型例です。

今日は、プロの現場で使っている「メモリリークを追い詰める究極の解析術」を伝授します。

1. なぜメモリリークが起きるのか?(メカニズムの理解)

メモリリークの正体は、「もう使わないのに、GCが『まだ必要だ』と勘違いしてメモリから解放できないオブジェクト」です。

VB.NETで最も多いリーク源はこれらです。

  • イベントハンドラの購読解除忘れ: フォームやクラスを閉じたつもりでも、イベントが接続されている限りGCは回収できません。
  • 静的メンバ(Shared)への参照: `Shared`リストに一度追加したオブジェクトは、アプリが終了するまでメモリに残り続けます。
  • アンマネージド資源: API(Win32 API等)から確保したメモリは、GCの管轄外です。`Dispose`を呼び忘れると、そこから確実に漏れます。

2. 現場で使う「メモリリーク解析」の武器

闇雲にコードを眺めてもリークは見つかりません。以下の2つのツールを使い分けます。

A. dotMemory(直感的な可視化)

JetBrains社のツールです。メモリの「今どこが使われているか」をグラフで可視化してくれます。「どの型が、どれだけ増え続けているか」を特定するのに最適です。

B. WinDbg(究極の外科手術)

マネージドコードの奥底を覗く、最後の手掛かりです。ダンプファイルを解析し、何がメモリを握りしめているか(GC Root)を逆算します。

3. リークを防ぐ:プロのコーディング・プラクティス

まずは、コードレベルでリークを防ぐ鉄則を身につけましょう。

鉄則1:IDisposableを遵守する

アンマネージド資源を扱うクラスは、必ず `Using` 構文で囲むか、明示的に `Dispose()` します。

‘ 悪い例: ネットワーク通信やファイル操作でリークしやすい
Dim client As New HttpClient()
‘ … ここで処理 …
‘ client.Dispose() を忘れると、ハンドルが漏れ続ける

‘ 良い例: Using構文で自動破棄を保証する
Using client As New HttpClient()
‘ このブロックを抜けると、自動的にDisposeが呼ばれる
Dim response = client.GetAsync(“https://api.example.com”).Result
End Using

鉄則2:イベントハンドラの解除(RemoveHandler)

画面(Form)を閉じた後も、その画面がどこかのイベントに紐付いていると、その画面全体がメモリに残り続けます。

‘ 購読する時
AddHandler myService.DataReceived, AddressOf OnDataReceived

‘ 画面を閉じる際や不要になった時に必ず解除する
RemoveHandler myService.DataReceived, AddressOf OnDataReceived

4. 実際にリークを特定する手順(WinDbgの入り口)

もしアプリが重くなったら、以下の手順で原因を絞り込みます。

1. ダンプの取得: タスクマネージャーで対象のプロセスを右クリックし、「ダンプファイルの作成」を選択します。
2. WinDbgで開く: ダンプをロードし、以下のコマンドを打ちます。

  • `!dumpheap -stat` : メモリを占拠しているオブジェクトのランキングを表示します。
  • `!gcroot <アドレス>` : 特定のオブジェクトが「なぜGCで回収されないのか」、その参照元を辿ります。

最後に:先輩からのアドバイス

メモリリークを見つける作業は、刑事ドラマの犯人探しに似ています。
「なぜこのオブジェクトは生き残っているのか?」という問いを常に持ち、「生成したものは、必ず片付ける」という強い意志を持ってください。

最初は難しく感じるかもしれませんが、dotMemoryで「メモリが綺麗な右肩下がり」になる様子を見れば、きっとその快感にハマるはずです。

VB.NETは、適切に扱えば非常に強力な武器になります。今日の知識を手に、ぜひ安定した業務アプリケーションを構築してください。応援しています!

タイトルとURLをコピーしました