VBScriptの「見えないメモリ泥棒」を退治せよ:`Set obj = Nothing` の真実
こんにちは。業務自動化の現場で数々のスクリプトと格闘してきたエンジニアです。
皆さんはVBScriptで自動化ツールを作っているとき、こんな経験はありませんか?
「最初は動いていたのに、ループを繰り返すうちにPCが重くなる」「Excelを操作するスクリプトを動かすと、タスクマネージャーにExcelのプロセスが大量に残り続ける」。
これはVBScript初心者が見落としがちな、「メモリ管理の闇」に足を踏み入れている証拠です。今日は、VBScriptにおけるオブジェクト解放の極意と、現場で生き残るための「後始末」の作法を伝授します。
—
1. なぜ「Nothing」が必要なのか?(参照カウントの仕組み)
VBScriptのメモリ管理は、「参照カウント方式」という仕組みで行われています。
簡単に言うと、「このオブジェクトを使っている人が一人でもいればメモリに置いておく。誰も使わなくなったら捨てる」というルールです。
`Set obj = CreateObject(…)` と書くと、VBScriptは「このオブジェクトを使うよ!」というカウントを1増やします。
しかし、スクリプトが終わっても、明示的に「もう使いません」と言わない限り、カウントが0にならず、メモリに居座り続けることがあるのです。これがメモリリークの正体です。
悪い例:解放を忘れた地獄
‘ ループの中で毎回Excelを呼び出すが、解放していない
For i = 1 To 100
Dim objExcel
Set objExcel = CreateObject(“Excel.Application”)
‘ … 何かの処理 …
‘ ここで objExcel = Nothing をしないと、
‘ ループの回数分だけExcelがメモリに溜まり続ける!
Next
このコードを実行すると、タスクマネージャーには100個ものExcelプロセスが並び、PCは悲鳴を上げます。
—
2. 巨大ループでメモリを枯渇させないための鉄則
ループ処理の中でオブジェクトを生成する場合、「ループの最後で必ず解放する」のが黄金律です。
良い例:クリーンアップを徹底する
Dim i, objFSO
‘ FileSystemObjectを生成
Set objFSO = CreateObject(“Scripting.FileSystemObject”)
For i = 1 To 1000
‘ ループ内で一時的に使用するオブジェクトは、その都度解放する
Dim objFile
Set objFile = objFSO.OpenTextFile(“C:\test\log.txt”, 8, True)
objFile.WriteLine “ログ出力: ” & i
‘ 使い終わったら即座に解放!
objFile.Close
Set objFile = Nothing
Next
‘ 最後に親オブジェクトも解放
Set objFSO = Nothing
ここでのポイントは、「使い終わった瞬間に解放する」という意識です。`Set obj = Nothing` は、いわば「ゴミ出し」です。ゴミを溜め込まないことが、安定した自動化への第一歩です。
—
3. 現場で陥りやすい「Excelがゾンビ化する」罠
特にExcel操作(`Excel.Application`)は要注意です。
Excelは非常に重いオブジェクトです。`Set objExcel = Nothing` をする前に、必ず `objExcel.Quit` を呼ぶ必要があります。
Dim objExcel
Set objExcel = CreateObject(“Excel.Application”)
‘ 処理が失敗しても確実に終了処理を通す工夫も重要
On Error Resume Next ‘ エラー発生時も止まらないようにする(現場の知恵)
‘ … Excel操作処理 …
‘ 1. まずExcel本体を閉じる
objExcel.Quit
‘ 2. 最後にメモリから解放する
Set objExcel = Nothing
On Error GoTo 0
`Quit` をせずに `Nothing` にしてしまうと、Excelのプロセスだけが裏で生き残り、ファイルがロックされて開けなくなる「ゾンビ現象」が発生します。これも現場でよくあるトラブルの一つです。
—
4. エンジニアとして、一歩先へ
ここまで意識できれば、あなたのスクリプトは既に「動く」レベルから「安定して稼働する」レベルへと進化しています。
最後に、これだけは覚えておいてください。
「オブジェクトは借り物である」という意識です。OSからメモリを借りて仕事をし、終わったら綺麗に返却する。この礼儀正しいプログラミングこそが、大規模な自動化を成功させる唯一の道です。
VBScriptは古い言語と言われますが、そのメモリ管理の本質は、現在のプログラミング言語にも通じる重要な教養です。ここをクリアしたあなたは、もう立派な自動化エンジニアの入り口に立っています。
次のスクリプトを書くときは、ぜひ `Set obj = Nothing` の一行に、あなたのエンジニアとしての誇りを込めてみてください。
それでは、良い自動化ライフを!
