Caché ObjectScript Reference
[Back] [Next]
Go to:

Contains the number of bytes available for local variable storage.
$STORAGE returns the number of bytes available for local variable storage in the current process partition. The initial value of $STORAGE is established by the value of $ZSTORAGE, the maximum amount of memory available to the process. The larger the $ZSTORAGE value (in kilobytes), the larger the $STORAGE value (in bytes). However, this relationship between $ZSTORAGE and $STORAGE is not a simple 1:1 ratio.
The $STORAGE value is affected by the following operations:
The $STORAGE value is not affected by setting process-private variables, global variables, or special variables. The $STORAGE value is not affected by changing namespaces. The $STORAGE value is not affected by enabling long strings because long string storage is not allocated in the process partition. For further details, refer to Long Strings in the “Data Types and Values” chapter of Using Caché ObjectScript.
The $STORAGE special variable cannot be modified using the SET command. Attempting to do so results in a <SYNTAX> error.
Low Memory and <STORE> Errors
The $STORAGE value may be a positive or negative number. A value of zero does not indicate no available storage, but indicates that storage is in extremely short supply. If $STORAGE decreases to less than zero, at some point a <STORE> error occurs. For example, if $STORAGE decreases to -7000, allocating storage for another local variable might fail due to a <STORE> error, indicating insufficient available storage space to store a local variable value, or to establish a new execution level.
The first <STORE> error occurs when $STORAGE is some value less than zero; the exact negative $STORAGE value threshold depends upon context. This <STORE> error indicates that you must get additional storage, either by increasing $ZSTORAGE, or by freeing some allocated storage through KILL or QUIT operations. When this first <STORE> error occurs, Caché automatically makes 1Mb of additional memory available to the process to enable error processing and recovery. Caché does not change $ZSTORAGE; it allows $STORAGE to go further into negative number values.
When this first <STORE> error occurs, Caché internally designates the process as being in a low memory state. While in this low memory state the process may continue to allocate memory and the value of $STORAGE may continue to decrease into lower negative numbers. While in this low memory state the process may free some allocated memory, causing the value of $STORAGE to rise. Thus, the value of $STORAGE may rise or fall within a range of values without issuing additional <STORE> errors. Also, after the first <STORE> error you may see a small rise in $STORAGE caused by Caché freeing some internal memory.
This first <STORE> error provides some memory cushion that allows your process to call diagnostics, perform saves to disk, exit gracefully, free memory, and continue.
A process remains in a low memory state until either of the following occurs:
You can determine the reason for a <STORE> error by calling the $SYSTEM.Process.MemoryAutoExpandStatus() method.
The following example shows how $STORAGE becomes smaller when $ZSTORAGE is set to a smaller value. Note that the relationship (ratio) between these two values is variable:
  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 }
The following example shows how $STORAGE decreases as local variables are assigned, and increases when local variables are killed:
  WRITE "$STORAGE=",$S," initial value",!
  FOR i=1:1:30 {SET a(i)="abcdefghijklmnopqrstuvwxyz"
    WRITE "$STORAGE=",$S,! }
  KILL a
  WRITE !,"$STORAGE=",$S," after KILL",!
The following example shows how the number of subscript levels of an assigned local variable affect $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)
The following example shows how $STORAGE decreases (becomes unavailable at that level) as NEW establishes a new execution level:
   WRITE "increasing levels:",!
   FOR i=1:1:10 {WRITE "$STORAGE=",$S,! NEW }
The following example shows how $STORAGE decreases as local variables are assigned until it enters low memory state, issuing a <STORE> error. The <STORE> error is caught by a CATCH block that invokes the StoreErrorReason() method to determine what caused the error. Note that entering the CATCH block consumes a significant amount of storage. Once in the CATCH block, this example allocates one more variable.
  TRY {
    WRITE !,"TRY block",!
    SET init=$ZSTORAGE
    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
See Also