docs.intersystems.com
Home  /  Application Development: Core Topics  /  ObjectScript Reference  /  ObjectScript Special Variables  /  $STORAGE


ObjectScript Reference
$STORAGE
[Back]  [Next] 
InterSystems: The power behind what matters   
Search:  


Contains the number of bytes available for local variable storage.
Synopsis
$STORAGE
$S
Description
$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 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, the system automatically makes 1Mb of additional memory available to the process to enable error processing and recovery. InterSystems IRIS does not change $ZSTORAGE; it allows $STORAGE to go further into negative number values.
When this first <STORE> error occurs, InterSystems IRIS 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 InterSystems IRIS 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.
Examples
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
    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
  }
See Also