【実務・中級編】【メモリ解放徹底ガイド】Erase ステートメントと ReDim を組み合わせた超巨大配列の明示的メモリ返還手法 – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク

VBScriptのメモリ管理を掌握せよ:巨大配列を確実に「消し去る」ための極限テクニック

業務自動化の現場において、VBScriptは今なお強力な武器だ。しかし、多くの開発者がメモリリークや「スクリプトの肥大化」という壁に突き当たり、途方に暮れる。

VBScriptのガベージコレクション(GC)は、現代の言語に比べれば非常に原始的だ。参照カウント方式を採用しているため、「変数がスコープを外れるまでメモリが解放されない」という致命的な弱点がある。数百万行のログ解析や、大量のデータベースレコードを配列に格納した瞬間、プロセスのメモリ消費量は跳ね上がり、最悪の場合はOSのリソースを食いつぶしてスクリプトがクラッシュする。

本記事では、このメモリの「負債」を完済し、システムを堅牢に保つための「メモリ解放の作法」を伝授する。

なぜ巨大配列のメモリ解放が「命題」なのか

VBScriptで `Dim arr(1000000)` のように巨大な配列を宣言すると、そのメモリ領域は即座に確保される。そして厄介なことに、処理が終わった後も、その配列変数が有効なスコープ内にある限り、メモリは解放されない。

単純に `arr = Empty` と書くのは素人のやり方だ。これでは参照先を書き換えているだけで、メモリ上のデータが即座にパージされる保証はない。我々が求めるのは、「OSにメモリを返還する」という確定的なアクションである。

【黄金の鉄則】Erase と ReDim の合わせ技

VBScriptにおいて、配列のメモリを論理的に切り離すための最も確実な手順は、「ReDim でサイズを最小化し、Erase で破棄する」という二段構えだ。

プロダクションコード例:メモリ管理を組み込んだ配列処理

‘ メモリ管理を徹底した配列処理のテンプレート
Sub ProcessLargeData()
Dim i, dataArray

‘ 1. 配列の動的確保(必要なサイズだけを確保する)
ReDim dataArray(999999)

‘ 2. データロード処理(DBやファイルからの読み込み)
For i = 0 To UBound(dataArray)
dataArray(i) = “レコード番号: ” & i
Next

‘ 3. ここで処理を行う
Call AnalyzeData(dataArray)

‘ — 【重要】ここからがメモリ解放の儀式 —

‘ ステップA: ReDimで最小サイズに縮小(OSへのメモリ再割り当てを促す)
ReDim dataArray(0)

‘ ステップB: Eraseで配列のメモリを明示的にクリア
‘ Eraseは動的配列に対してメモリを解放する役割を果たす
Erase dataArray

‘ ステップC: 参照を明示的にEmptyにする(念押し)
dataArray = Empty

‘ —————————————
End Sub

Sub AnalyzeData(ByRef arr)
‘ 参照渡しで処理を行う。ここでコピーが発生しないよう注意すること
‘ 配列を引数にする際は必ずByRefを意識せよ
End Sub

実務で陥る「罠」と設計の注意点

1. グローバル変数の回避

巨大な配列をモジュールのトップレベル(グローバルスコープ)で定義してはならない。グローバル変数は、スクリプトが終了するまでメモリに居座る。必ず `Sub` や `Function` 内でローカル変数として定義し、スコープを抜ける前に明示的に解放する設計を徹底すること。

2. ファイル・DB連携時のバッファリング

データベースから数万件のレコードを一括で `GetRows` すると、メモリは一瞬で枯渇する。

  • 悪い例: `arr = objRS.GetRows()` で全件取得
  • 良い例: レコードセットをループさせ、必要な分だけを処理し、都度クリアする。どうしても配列が必要なら、チャンク(塊)単位で処理を分割しろ。

3. オブジェクトの解放 (Nothing) も忘れずに

配列だけでなく、`ADODB.Recordset` や `FileSystemObject` も同様だ。`Set obj = Nothing` を記述しなければ、COMオブジェクトの参照カウントはゼロにならず、メモリ上にゾンビのように残り続ける。

アーキテクトからの助言

「コピペで動く」ことは最低条件に過ぎない。君たちが書くコードは、数年後に別の担当者が保守することになる。

メモリ管理を意識するということは、「自分が使ったリソースの責任を持つ」ということだ。リソースを使いっぱなしにするスクリプトは、単なるバグ生産機である。`Erase` を使い、`Nothing` を呼び、`Empty` にする。この小さな規律の積み重ねこそが、深夜のシステムダウンを防ぐ唯一の盾となる。

さあ、コードを書き換えろ。そして、君たちのスクリプトを、誰よりも軽快で信頼性の高いものに進化させるんだ。