【実務・中級編】CONTROLLED属性による明示的なメモリ管理 – PL/Iの基本構文とデータ制御実践ガイド

枯れた技術の深淵:PL/IにおけるCONTROLLED属性によるメモリ管理の流儀

やあ、今日もメインフレームの保守作業、お疲れ様。
「PL/Iなんて古い」と言う若手もいるが、数千万行のVSAMファイルを捌き、深夜のバッチウィンドウで一度の停止も許されないミッションクリティカルなシステムを支えているのは、今なおこの言語だ。

今日は、特にバッチプログラムのメモリ効率に直結するCONTROLLED属性について話をしよう。自動変数(Automatic)に頼り切ったコーディングをしていると、大規模なデータセットを扱う際にスタックオーバーフローや、不必要な領域確保によるパフォーマンス低下を招く。ここでは、プログラマが主導権を握るメモリ管理の「型」を伝授する。

1. CONTROLLED属性とは何か:メモリの「借用」と「返却」

通常、PL/Iで宣言された変数はスタック上に確保されるが、`CONTROLLED`属性を付与すると、プログラムの実行中に`ALLOCATE`(確保)と`FREE`(解放)を明示的に行う必要がある。

これは、「必要な時に、必要な分だけ借りて、使い終わったら即座に返す」という、極めて規律正しいメモリ管理だ。特に、VSAMからの読み込み件数が実行時まで不明な動的配列や、巨大な構造体を扱う際には、この制御が生命線となる。

2. 実践:CONTROLLED変数を用いた構造体処理

以下のコード例を見てほしい。VSAMファイルからレコードを読み込み、メモリ上に一時保存して複雑な集計を行う典型的なバッチ処理の断片だ。

1
/ —————————————————————— /
/ プログラム名: BATCH_CONTROLLED_EXAMPLE /
/ 概要: CONTROLLED属性による動的メモリ確保のデモンストレーション /
/ —————————————————————— /
DEMO_PROC: PROCEDURE OPTIONS(MAIN);

/ 構造体の定義 – 確保するメモリのテンプレート /
DCL 1 WORK_REC CONTROLLED,
2 KEY_ID CHAR(10),
2 DATA_VAL BIN FIXED(15),
2 DESC CHAR(50);

DCL N_COUNT FIXED BIN(31) INIT(0);
DCL I FIXED BIN(31);

/ 確保のタイミングはプログラムの意志で決定する /
ALLOCATE WORK_REC;

/ 擬似的にVSAMからデータを読み込む想定 /
WORK_REC.KEY_ID = ‘RECORD-001’;
WORK_REC.DATA_VAL = 100;

/
重要な注意点:
同じ名前の変数を再度ALLOCATEすると、スタックのように積まれる。
これを「スタック効果」と呼ぶが、意図しない多重確保はバグの温床。
FREE時には最新の確保分から順次解放される。
/
FREE WORK_REC;

/ メモリ解放を確認するためにBUILTIN関数を使用 /
IF ALLOCATION(WORK_REC) = 0 THEN
PUT SKIP LIST(‘メモリは正常に解放されました’);

END DEMO_PROC;

3. 現場で嵌まる「地雷」とデバッグのコツ

CONTROLLED変数を扱う際、現場でよく見る悲劇は「FREEのし忘れ」「多重ALLOCATEによるスタックの肥大化」だ。

ONユニットで安全策を講じる

万が一、メイン処理中に例外が発生した場合、`FREE`ステートメントがスキップされる可能性がある。これを防ぐために、`ON CONDITION`や`ON ERROR`で異常終了時の後始末を記述する癖をつけよう。

1
ON ERROR BEGIN;
PUT SKIP LIST(‘エラー発生。メモリをクリーンアップします’);
/ 異常終了時も安全に解放を試みる /
DO WHILE(ALLOCATION(WORK_REC) > 0);
FREE WORK_REC;
END;
SIGNAL FINISH;
END;

デバッグ時の視点

もし「理由不明のS0C4やストレージ枯渇」が発生したら、真っ先に`ALLOCATION(変数名)`を確認すること。これはPL/IのBUILTIN関数であり、実行時にその変数が何回確保されているかを返してくれる。デバッグプリントにこれを出力させるだけで、メモリリークの箇所は一発で特定できる。

最後に:アーキテクトからのアドバイス

最近のマイグレーション現場では、こうした古い言語仕様を「ブラックボックス化」して放置する傾向があるが、それは危険だ。CONTROLLED属性を使いこなすことは、単なる節約術ではない。「システムのリソースを、誰が、いつ、どの範囲まで責任を持つか」という設計思想の表れなんだ。

コードを記述する際は、常に「このメモリはいつ解放されるべきか?」を自問自答してほしい。その丁寧さが、数年後の保守担当者を救い、何より君自身のエンジニアとしての確固たる自信になるはずだ。

また何か具体的なトラブルや、複雑な構造体の移行で悩んだら、いつでも相談に来てくれ。PL/Iの奥深さを、共に解き明かそう。

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