第十五章 Caché 變數大全 $STORAGE 變數
技術標籤:Caché 變數大全CachéCachestorage記憶體變數位元組數
文章目錄
第十五章 Caché 變數大全 $STORAGE 變數
包含可用於區域性變數儲存的位元組數。
大綱
$STORAGE
$S
描述
$STORAGE
返回可用於當前程序分割槽中的本地變數儲存的位元組數。 $STORAGE
的初始值由$ZSTORAGE
的值確定,該值是該程序可用的最大記憶體量。 $ZSTORAGE
值(以千位元組為單位)越大,$STORAGE
值(以位元組為單位)越大。但是,$ZSTORAGE
$STORAGE
之間的關係不是簡單的1:1比率。
$STORAGE
值受以下操作影響:
- 在區域性變數空間中定義區域性變數(例如,使用
set
命令)時,$STORAGE
會減少。$STORAGE
的減少對應於儲存區域性變數的值所需的空間量;區域性變數名稱的大小對$STORAGE
沒有影響,但下標級別的數量確實會影響$STORAGE
。$STORAGE
值隨著刪除區域性變數(例如,通過使用kill
命令)而增加。 - 發出
NEW
命令時,$STORAGE
會減少。NEW
建立一個新的執行級別;在上一個執行級別為區域性變數(無論是否使用)預留的空間在新的執行級別上不可用。最初的new
專案減少了大約15000的$STORAGE
;後續的每個new
$STORAGE
。發出QUIT
命令退出執行級別時,$STORAGE
值會增加。 - 當定義控制流語句(如
IF
或FOR
)或塊結構(如TRY
和CATCH
)時,$STORAGE
會減少。分配儲存是用來編譯這些結構的,而不是用來執行它們的。因此,無論是否迴圈或迴圈多少次,For
語句都會消耗相同的儲存量;無論執行多少分支,每個If
、ELSEIF
和ELSE
子句都會消耗一定數量的儲存。空間是從編譯程式碼的程序分配的。請注意,for
迴圈通常將區域性變數定義為計數器。
$STORAGE
值不受設定程序私有全域性變數、全域性變數或特殊變數的影響。$STORAGE
值不受更改名稱空間的影響。啟用長字串不會影響$STORAGE
不能使用SET
命令修改$STORAGE
特殊變數。嘗試這樣做會導致<SYNTAX>
錯誤。
記憶體不足和<store>
錯誤
$STORAGE
值可以是正數,也可以是負數。值為零並不表示沒有可用儲存,但表示儲存極度短缺。如果$STORAGE
減少到小於零,則會在某個時刻發生<store>
錯誤。例如,如果$STORAGE
減少到-7000,則為另一個區域性變數分配儲存可能會由於<store>
錯誤而失敗,這表明沒有足夠的可用儲存空間來儲存區域性變數值或建立新的執行級別。
第一個<store>
錯誤發生在$STORAGE
的某個值小於零時;確切的負$STORAGE
值閾值取決於上下文。此<store>
錯誤指示必須通過增加$ZSTORAGE
或通過KILL
或QUIT
操作釋放一些已分配的儲存來獲得額外的儲存。當第一個<store>
錯誤發生時,Caché會自動為程序提供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時,會出現第二個<STORE>
錯誤。如果程序到達這一點,則沒有更多的記憶體可供該程序使用,並且進一步的程序操作將變得不可預測。這一過程很可能會立即終止。
可以通過呼叫$SYSTEM.Process.MemoryAutoExpanStatus()
方法來確定<store>
錯誤的原因。
示例
以下示例顯示當$ZSTORAGE
設定為較小的值時,$STORAGE
如何變小。請注意,這兩個值之間的關係(比率)是可變的:
/// d ##class(PHA.TEST.SpecialVariables).STORAGE()
ClassMethod STORAGE()
{
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
如何減少,而在終止區域性變數時$STORAGE
如何增加:
/// d ##class(PHA.TEST.SpecialVariables).STORAGE1()
ClassMethod STORAGE1()
{
WRITE "$STORAGE=",$S," initial value",!
FOR i=1:1:30 {
SET a(i)="abcdefghijklmnopqrstuvwxyz"
WRITE "$STORAGE=",$S,!
}
KILL a
WRITE !,"$STORAGE=",$S," after KILL",!
}
DHC-APP>d ##class(PHA.TEST.SpecialVariables).STORAGE1()
$STORAGE=22551864 initial value
$STORAGE=22551728
$STORAGE=22551664
$STORAGE=22551408
$STORAGE=22551344
$STORAGE=22551280
$STORAGE=22551216
$STORAGE=22551152
$STORAGE=22551088
$STORAGE=22551024
$STORAGE=22550960
$STORAGE=22550896
$STORAGE=22550832
$STORAGE=22550768
$STORAGE=22550704
$STORAGE=22550640
$STORAGE=22550320
$STORAGE=22550256
$STORAGE=22550192
$STORAGE=22550128
$STORAGE=22550064
$STORAGE=22550000
$STORAGE=22549936
$STORAGE=22549872
$STORAGE=22549808
$STORAGE=22549744
$STORAGE=22549680
$STORAGE=22549616
$STORAGE=22549552
$STORAGE=22549488
$STORAGE=22549424
$STORAGE=22551856 after KILL
以下示例顯示分配的區域性變數的下標級別數如何影響$STORAGE
:
/// d ##class(PHA.TEST.SpecialVariables).STORAGE2()
ClassMethod STORAGE2()
{
WRITE "無下標:",!
SET before=$S
SET a="abcdefghijklmnopqrstuvwxyz"
WRITE " 分配的記憶體 ",before-$S,!
KILL a
WRITE "1個下標級別:",!
SET before=$S
SET a(1)="abcdefghijklmnopqrstuvwxyz"
WRITE " 分配的記憶體 ",before-$S,!
KILL a(1)
WRITE "9個下標級別:",!
SET before=$S
SET a(1,2,3,4,5,6,7,8,9)="abcdefghijklmnopqrstuvwxyz"
WRITE " 分配的記憶體 ",before-$S,!
KILL a(1,2,3,4,5,6,7,8,9)
}
DHC-APP>d ##class(PHA.TEST.SpecialVariables).STORAGE2()
無下標:
分配的記憶體 80
1個下標級別:
分配的記憶體 128
9個下標級別:
分配的記憶體 640
以下示例顯示了當NEW
建立新的執行級別時,$STORAGE
如何減少(在該級別變得不可用):
/// d ##class(PHA.TEST.SpecialVariables).STORAGE3()
ClassMethod STORAGE3()
{
WRITE "不斷增加的級別:",!
FOR i=1:1:10 {
WRITE "$STORAGE=",$S,! NEW
}
}
DHC-APP>d ##class(PHA.TEST.SpecialVariables).STORAGE3()
不斷增加的級別:
$STORAGE=22550456
$STORAGE=22536704
$STORAGE=22524416
$STORAGE=22512128
$STORAGE=22499840
$STORAGE=22487552
$STORAGE=22475264
$STORAGE=22462976
$STORAGE=22450688
$STORAGE=22438400
下面的示例顯示了$STORAGE
如何隨著區域性變數的賦值而減少,直到它進入記憶體不足狀態,併發出<store>
錯誤。<store>
錯誤由Catch
塊捕獲,該塊呼叫StoreErrorReason()
方法來確定導致錯誤的原因。請注意,進入CATCH
塊會消耗大量儲存空間。一旦進入CATCH
塊,此示例將再分配一個變數。
/// d ##class(PHA.TEST.SpecialVariables).STORAGE4()
ClassMethod STORAGE4()
{
TRY {
WRITE !,"TRY 塊",!
SET init=$ZSTORAGE
SET $ZSTORAGE=456
WRITE "初始化 $STORAGE=",$STORAGE,!
FOR i=1:1:10000 {
SET pre=$STORAGE
SET var(i)="1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
IF $STORAGE<0 {
WRITE "var(",i,") 負記憶體=",$STORAGE,!
} ELSEIF pre<$STORAGE {
WRITE "var(",i,") 新分配 $S=",$STORAGE,!
} ELSE {
WRITE "var(",i,") $S=",$STORAGE,!
}
}
}
CATCH myexp {
WRITE !,"CATCH 塊異常處理",!!
WRITE "Name: ",$ZCVT(myexp.Name,"O","HTML"),!
IF myexp.Name="<STORE>" {
WRITE "記憶體錯誤原因=",
$SYSTEM.Process.StoreErrorReason(),!
}
WRITE "$S=",$STORAGE,!
SET j=i
SET var(j)="1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
WRITE "var(",j,") 增加了一個變數 $S=",$STORAGE,!
SET $ZSTORAGE=init
RETURN
}
}
...
var(2039) $S=48152
var(2040) $S=48024
var(2041) $S=47896
var(2042) $S=47768
var(2043) $S=47640
var(2044) $S=47512
var(2045) $S=47384
var(2046) $S=47256
var(2047) $S=47128
CATCH 塊異常處理
Name: <STORE>
記憶體錯誤原因=1
$S=39240
var(2048) 增加了一個變數 $S=6336