メインフレームの闇を照らす:CONTROLLED変数の生存確認とALLOCATION関数の極意
若手の諸君、日々のジョブ制御やレガシーなソースコードの解析、ご苦労様。
今日は、PL/Iにおけるメモリ管理の肝、「CONTROLLED属性」と、その状態を監視する「ALLOCATIONビルトイン関数」について深掘りしよう。
大規模な基幹システムにおいて、静的なストレージ確保(STATIC)だけで完結するプログラムは稀だ。レコードの読み込み件数が予測不能なバッチ処理や、VSAMの動的アクセスが必要なケースでは、どうしてもヒープを制御する必要が出てくる。そこで登場するのが `CONTROLLED` だが、こいつは諸刃の剣でもある。不用意な `FREE` や、二重の `ALLOCATE` は、システムダウンを招く典型的な「地雷」だ。
1. なぜ「今、確保されているか」を知る必要があるのか
PL/Iのメモリ管理において、`CONTROLLED` 変数はスタック状に積み上げられる。`ALLOCATE` を叩くたびに新しい世代が生成され、`FREE` を叩くと最新の世代が破棄される。
問題は、「現在のポインタが何を指しているか」「本当にこの変数はメモリに存在しているのか」を論理的に追いきれなくなった時だ。特に、複雑なサブルーチンを跨ぐような処理や、`ON-UNIT` で例外を捕捉した直後のリカバリ処理において、変数の生存確認を怠ると、予期せぬ `STORAGE CONDITION` やポインタ例外に直面する。
ここで頼りになるのが `ALLOCATION(変数名)` ビルトイン関数だ。これは、その変数が現在スタック上に何世代存在するかを整数で返してくれる。
2. 実践コード:堅牢なメモリ管理の作法
以下のコード例を見てほしい。VSAMファイルからレコードを読み込み、動的に確保したバッファを制御する際の定石だ。
1
/——————————————————————-/
/ プログラム名: DATA_MGR /
/ 概要: CONTROLLED変数を用いた動的メモリ管理と生存確認のデモ /
/——————————————————————-/
TEST_PROC: PROCEDURE OPTIONS(MAIN);
/ 制御対象の変数をCONTROLLED属性で宣言 /
DCL WORK_BUF CHAR(1024) CONTROLLED;
/ ファイル定義とONユニット /
DCL VSAM_FILE FILE RECORD INPUT;
ON ENDFILE(VSAM_FILE) BEGIN;
PUT SKIP LIST(‘EOF REACHED’);
END;
/ 処理開始 /
PUT SKIP LIST(‘ALLOCATION COUNT:’, ALLOCATION(WORK_BUF));
/ 必要なタイミングでメモリを確保 /
ALLOCATE WORK_BUF;
/ ALLOCATION関数で確実に確保されたかを確認する /
IF ALLOCATION(WORK_BUF) > 0 THEN DO;
PUT SKIP LIST(‘メモリ確保成功。現在の世代数:’, ALLOCATION(WORK_BUF));
/ ここでVSAM読み込み等の処理を行う /
END;
/ 処理終了後の解放。二重FREEを防ぐための防衛的コーディング /
IF ALLOCATION(WORK_BUF) > 0 THEN
FREE WORK_BUF;
/ 念のための確認 /
PUT SKIP LIST(‘解放後の確保数:’, ALLOCATION(WORK_BUF));
END TEST_PROC;
3. ベテランからのアドバイス:デバッグの現場で
この `ALLOCATION` 関数、単なる状態確認以上の価値がある。特に大規模なマイグレーション時や、既存の複雑なバッチを改修する際、以下のようなシーンで威力を発揮する。
- 再帰呼び出し時のスタック深さの追跡:
`ALLOCATE` がループ内で実行されるようなロジックでは、意図せず世代数が増え続け、メモリを食いつぶすことがある。`ALLOCATION` の値をログに出力するだけで、リークの有無が即座に判別できる。
- ON-UNIT内でのクリーンアップ:
`ON STORAGE` や `ON ERROR` の中で、どの変数が確保されたまま異常終了したのかを特定する際、この関数をデバッグ用の `PUT` 文に組み込むことで、問題の所在を即座に特定できる。
最後に
PL/Iのコードは、書いた人の「誠実さ」がそのまま現れる。`ALLOCATE` を書いたら、必ず対になる `FREE` を意識すること。そして、その制御が怪しいと感じたら、迷わず `ALLOCATION` 関数で「現在の状態」を問い直すことだ。
コンパイラは優秀だが、メモリの論理的な意味までは理解してくれない。システムを止めないエンジニアは、常に「今、何がメモリにあるのか」を頭の中にマップとして描いているものだ。
現場で困ったことがあれば、またいつでも聞いてくれ。基本に忠実かつ、油断のないコードを書いていこうぜ。
