【テクニカル・上級編】ALLOCATE文による動的メモリ確保とストレージ不足時のON条件 – PL/Iの基本構文とデータ制御実践ガイド

汎用機の深淵:PL/I動的メモリ管理と「STORAGE」例外の攻防

IBMメインフレームの現場で、PL/Iのコードを眺めていると時折遭遇する「動的メモリ確保」の壁。特に、レガシーシステムの移行や、数十年にわたるバッチ処理の改修において、`ALLOCATE`文とポインタ操作は、システム全体の安定性を左右する最後の砦です。

今回は、ヒープ領域(PL/I用語でいうストレージ・プール)を巡る動的メモリ確保の勘所と、それが枯渇した際に発生する`STORAGE`条件のハンドリング、そして移行担当者が必ず直面する「ダンプ解析」の泥沼について語ります。

1. 動的メモリ確保の構造:BASE変数とポインタの相関

PL/Iにおいて、`ALLOCATE`は単なるメモリ確保ではありません。それは、`BASED`ストレージ属性を持つ変数と、そのアドレスを保持するポインタ変数の「契約」です。

/i
DCL MY_BUFFER CHAR(32767) BASED(P_BUFFER);
DCL P_BUFFER POINTER;

/ ヒープから32KBを確保 /
ALLOCATE MY_BUFFER;

/ 確保した領域へのアクセス。P_BUFFERには自動的にアドレスが格納される /
SUBSTR(MY_BUFFER, 1, 10) = ‘HEADER_INFO’;

/ 使い終わったら解放。これを忘れるとメモリリークの温床になる /
FREE MY_BUFFER;

ここで重要なのは、`ALLOCATE`が発行された際、ランタイムライブラリ(LE/370)がどのヒープ(`ANYHEAP`なのか`BELOWHEAP`なのか)からメモリを切り出すかという点です。CICS環境下では、ここを誤ると「ストレージ保護違反」や「タスク間のメモリ干渉」を引き起こす原因となります。

2. STORAGE条件:例外処理の作法

もしヒープが枯渇した場合、PL/Iは`STORAGE`条件を発生させます。これを放置すれば即座にABEND(S0C4やS0C1への布石)ですが、適切にトラップすれば、処理を安全に中断させることが可能です。

/i
ON STORAGE BEGIN;
/ ログ出力やキューへの退避など、再起動可能な状態を整える /
PUT SKIP LIST(‘!!! FATAL: STORAGE EXHAUSTED. EMERGENCY SHUTDOWN.’);
CALL DUMP_CONTEXT_INFO; / 独自のダンプ情報取得 /
SIGNAL FINISH; / 正常に処理を終了させる /
END;

アーキテクトの視点:
実務レベルでは、単にエラーを出すだけでなく、「何が原因でヒープを食い潰したのか」を記録することが肝要です。特に、CICSの擬似会話型トランザクションで`ALLOCATE`をループさせている場合、解放し忘れによるメモリリークがじわじわとメモリを圧迫します。`STORAGE`条件が発生した時点で、ヒープの統計情報を出すようLEオプション(`RPTSTG(ON)`)を付与しておくのが、プロの定石です。

3. マイグレーションにおける罠:パックデシマルと内部表現

PL/IからJava等へ移行する際、最も頭を抱えるのが「パックデシマル(`FIXED DEC`)」の扱いと、ポインタ経由の構造体コピーです。

例えば、PL/Iの構造体で定義されたパックデシマルが、DB2の埋め込みSQLを通じて取得される際、内部符号が`0C`や`0D`であることを前提としたロジックが組まれていることが多々あります。

  • 問題の核心: Javaの`BigDecimal`への変換時に、符号が正しく認識されず、マイナス値がプラスとして評価されるケース。
  • 対策: 移行設計では、必ず`DUMP`コマンドでメモリ上の16進数ダンプを確認し、パックデシマルの符号ビットがどうなっているかを物理的に検証してください。

4. ダンプ解析のポイント:アベンド発生時の「地図」

S0C4(アドレッシング例外)やS0C7(データ例外)で停止した場合、PL/Iの`CEE3DMP`が生成するダンプは、情報の宝庫です。

1. ポインタの妥当性: ダンプ内の`P_BUFFER`の値を確認してください。確保直後に`NULL()`ではないか、あるいは`FREE`した後の「ぶら下がりポインタ」を参照していないか。
2. コンパイラ最適化の影響: `OPTIMIZE(2)`以上でコンパイルされたコードは、レジスタへの変数の割り当てが激しく、ダンプを見ただけでは変数の値が追えないことがあります。トラブルシューティング時は、該当モジュールのみ`OPTIMIZE(0)`で再コンパイルし、挙動を再現させるのが近道です。

結論:コードの先にある「意味」を読み解く

PL/Iは、ハードウェアの挙動を直接制御できる最後の「高級言語」です。JavaやC#といったマネージド言語への移行を行う際、単に構文を書き換えるだけでは不十分です。

「なぜこの`ALLOCATE`がここにあるのか」「なぜこのメモリサイズでなければならなかったのか」。その背景にある基幹業務の重みを理解し、メモリ管理のアーキテクチャまでを現代的な設計に昇華させること。それこそが、我々アーキテクトに課せられた、真のレガシーモダナイゼーションです。

次にダンプと向き合う時、それは単なるエラーコードの羅列ではなく、システムが発している「悲鳴」として聞こえてくるはずです。その時こそ、あなたのアーキテクトとしての真価が問われる瞬間です。

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