Skip to main content

This is documentation for Caché & Ensemble. See the InterSystems IRIS version of this content.Opens in a new tab

For information on migrating to InterSystems IRISOpens in a new tab, see Why Migrate to InterSystems IRIS?

$STORAGE

ローカル変数ストレージに使用できるバイト数を含みます。

Synopsis

$STORAGE
$S

概要

$STORAGE は、現在のプロセスのパーティションで、ローカル変数ストレージに利用できるバイト数を返します。$STORAGE の初期値は、プロセスで使用できる最大メモリ量である $ZSTORAGE の値により、確立されます。$ZSTORAGE の値 (キロバイト) が増えると、$STORAGE の値 (バイト) も増えます。ただし、$ZSTORAGE$STORAGE の関係は、単純な 1:1 の比とはなりません。

$STORAGE の値は、以下の処理によって影響を受けます。

  • $STORAGE の値は、SET コマンドなどの使用により、ローカル変数がローカル変数の領域で定義されると減少します。$STORAGE の減少は、ローカル変数の値を格納するために必要な領域の容量に関係します。ローカル変数の名前のサイズは、$STORAGE に影響しませんが、添え字レベルの数値は $STORAGE に影響します。$STORAGE の値は、KILL コマンドなどを使用してローカル変数が削除されると増大します。

  • $STORAGE は、NEW コマンド発行時に減少します。NEW は、新規の実行レベルを確立します。前回の実行レベルでローカル変数に対して設定された領域は (使用の有無に関係なしに)、新規の実行レベルでは使用できません。最初の NEW により、$STORAGE は約 15000 減少します。以降の各 NEW により、$STORAGE は 12288 減少します。$STORAGE の値は、QUIT コマンドを発行して、実行レベルを終了させると増大します。

  • $STORAGE は、IFFOR などのフロー制御文、または TRYCATCH などのブロック構造を定義したときに減少します。ストレージは、これらの構造を実行するためではなく、コンパイルするために割り当てられます。したがって、FOR 文は、ループの有無やループの回数に関係なく、同じストレージ容量を消費します。IFELSEIF、および ELSE 節は、実行される分岐の数に関係なく、それぞれ設定されたストレージ容量を消費します。領域は、コードをコンパイルしたプロセスから割り当てられます。通常、FOR ループは、ローカル変数をカウンタとして定義することに注意してください。

$STORAGE の値は、プロセス・プライベート変数、グローバル変数、または特殊変数の設定により影響を受けません。$STORAGE の値には、ネームスペースの変更による影響はありません。$STORAGE 値は長い文字列を有効にしても影響がありません。この理由は、長い文字列のストレージをプロセスのパーティションに割り当てないからです。詳細は、"Caché ObjectScript の使用法" の “データ型とデータ値” の章の "長い文字列" を参照してください。

$STORAGE 特殊変数は、SET コマンドを使用して変更することはできません。変更を試みると、<SYNTAX> エラーが返されます。

ローメモリと <STORE> エラー

$STORAGE の値は、正または負の数値とすることができます。値 0 は、使用できるストレージがないことを示すのではなく、ストレージが非常に不足していることを示します。$STORAGE が 0 未満に減少した場合、ある時点で <STORE> エラーが発生します。例えば、$STORAGE が -7000 に減少した場合、別のローカル変数に対してストレージを割り当てると、ローカル変数値の格納や新しい実行レベルの確立に利用可能なストレージ領域が不足していることを示す <STORE> エラーが返され、失敗する可能性があります。

最初の <STORE> エラーは、$STORAGE が 0 未満のある値になったときに発生しますが、正確な負の $STORAGE 値のしきい値は状況により異なります。この <STORE> エラーは、$ZSTORAGE を増加するか、KILL または QUIT 処理で一部の割り当て済みのストレージを解放することで、ストレージを追加する必要があることを示します。この最初の <STORE> エラーが発生すると、システムは、自動的に 1Mb の追加メモリをプロセスに提供し、エラー処理およびリカバリを行えるようにします。Caché は $ZSTORAGE を変更せず、$STORAGE が負の数値になるのを許容します。

この最初の <STORE> エラーが発生すると、Caché は、内部で「ローメモリ状態にあるプロセス」としてプロセスを指定します。このローメモリ状態にある間、プロセスがメモリの割り当てを継続し、$STORAGE の値がさらに小さい負の数値に減少し続ける場合があります。このローメモリ状態にある間、プロセスが割り当てメモリの一部を解放し、$STORAGE の値が上昇する場合があります。したがって、$STORAGE の値は、新たな <STORE> エラーを出すことなく、値の範囲内で増減します。また、最初の <STORE> エラーの後に、Caché が一部の内部メモリを解放することで $STORAGE の値がわずかに上昇する場合があります。

この最初の <STORE> エラーが発生すると、予備のメモリが提供されます。これにより、プロセスは、診断機能を呼び出し、ディスクへの保存を実施し、正常に終了し、メモリを解放して、続行することが可能になります。

プロセスは、以下のいずれかが行われるまでローメモリ状態のままです。

  • プロセスで十分なメモリを使用可能にします。$ZSTORAGE の割り当てを増加させたり、KILL または QUIT 処理によって割り当て済みストレージを解放したりすることで、プロセスはこれを行うことができます。$STORAGE の値が 256K (または $ZSTORAGE の 25%、いずれか小さい方) を超えると、Caché によってそのプロセスのローメモリ状態が解除されます。使用可能メモリが負の数値に減少した場合、その時点で再び <STORE> エラーがプロセスによって出される場合があります。

  • プロセスは追加のメモリを消費します。$STORAGE の値が -1048576 に達すると、2 回目の <STORE> エラーが発生します。プロセスがこの時点に到達した場合、プロセスはこれ以上メモリを使用できず、それ以降のプロセス処理は予測不能になります。おそらくプロセスは直ちに終了します。

$SYSTEM.Process.MemoryAutoExpandStatus()Opens in a new tab メソッドを呼び出すことで <STORE> エラーの理由を判別できます。

以下の例では、$ZSTORAGE に少ない値が設定された場合、どのように $STORAGE も少なくなるかを示します。これらの 2 つの値の関係 (比) は可変であることに注意してください。

  SET $ZS=262144
  FOR i=1:1:10 {
          WRITE "$ZS=",$ZS," $S=",$S," ratio=",$NORMALIZE($S/$ZS,3),!
          IF $ZS>30000 {SET $ZS=$ZS-30000 }
  }

以下の例では、ローカル変数が割り当てられた場合、どのように $STORAGE が減少するか、またローカル変数が削除された場合、どのように増加するかを示します。

  WRITE "$STORAGE=",$S," initial value",!
  FOR i=1:1:30 {SET a(i)="abcdefghijklmnopqrstuvwxyz"
    WRITE "$STORAGE=",$S,! }
  KILL a
  WRITE !,"$STORAGE=",$S," after KILL",!

以下の例では、割り当てられたローカル変数の添え字レベルの数が $STORAGE にどのように影響するかを示しています。

  WRITE "No subscripts:",!
  SET before=$S
  SET a="abcdefghijklmnopqrstuvwxyz"
  WRITE " memory allocated ",before-$S,!
  KILL a
  WRITE "One subscript level:",!
  SET before=$S
  SET a(1)="abcdefghijklmnopqrstuvwxyz"
  WRITE " memory allocated ",before-$S,!
  KILL a(1)
  WRITE "Nine subscript levels:",!
  SET before=$S
  SET a(1,2,3,4,5,6,7,8,9)="abcdefghijklmnopqrstuvwxyz"
  WRITE " memory allocated ",before-$S,!
  KILL a(1,2,3,4,5,6,7,8,9)

以下の例では、NEW による新規実行レベル確立で、どのように $STORAGE が減少するか (そのレベルでの使用が不可能となるか) を示します。

   WRITE "increasing levels:",!
   FOR i=1:1:10 {WRITE "$STORAGE=",$S,! NEW }

以下の例では、ローメモリ状態になるまで、ローカル変数が割り当てられた際に、$STORAGE がどのように減少していき、<STORE> エラーが出されるかを示しています。<STORE> エラーは、StoreErrorReason() メソッドを呼び出して、エラーの原因を判別する CATCH ブロックによって捕捉されます。CATCH ブロックに入ると大量のストレージを消費することに注意してください。CATCH ブロックに入った後、この例では、変数をもう一つ割り当てています。

  TRY {
    WRITE !,"TRY block",!
    SET init=$ZSTORAGE
    SET $ZSTORAGE=456
    WRITE "Initial $STORAGE=",$STORAGE,!
    FOR i=1:1:1000 {
       SET pre=$STORAGE
       SET var(i)="1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
       IF $STORAGE<0 {WRITE "var(",i,") negative memory=",$STORAGE,! }
       ELSEIF pre<$STORAGE {WRITE "var(",i,") new allocation $S=",$STORAGE,! }
       ELSE {WRITE "var(",i,") $S=",$STORAGE,! }
    }
  }
  CATCH myexp {
      WRITE !,"CATCH block exception handler",!!
      WRITE "Name: ",$ZCVT(myexp.Name,"O","HTML"),!
        IF myexp.Name="<STORE>" {WRITE "store error reason=",
                                 $SYSTEM.Process.StoreErrorReason(),! }
      WRITE "$S=",$STORAGE,!
      SET j=i
      SET var(j)="1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
      WRITE "var(",j,") added one more variable $S=",$STORAGE,!
      SET $ZSTORAGE=init
      RETURN
  }

関連項目

FeedbackOpens in a new tab