2016-11-11 1 views
1

私のtclアプリケーションは、辞書を使用して大きなデータベースを格納しており、メモリが大幅に爆発しないようにする必要があります。私は辞書全体のメモリを解放する簡単なアプローチを探しています。新しい空のdictが割り当てられている場合、tclは既存のdict変数のメモリを解放しますか?

以下のコードシーケンスでは、既に大きなサイズの辞書が関連付けられている変数に空白の辞書を再割り当てしています。変数付きの新しいdictの内容が空であることがわかりますが、メモリを解放しますか?言い換えれば、これはキーと値のペアに対してunset文を実行するのと同じですか?

set db [dict create] 
dict set db key1 value1 
dict set db key2 value2 

# Will this next step recover memory of all previous key-value assignments? 
set db [dict create] 
+1

Afaik、Tclはオペレーティングシステムにメモリを返しませんが、辞書に使用されたメモリは再利用されます。 –

+0

その場合、上記のコードはTclに以前に占有されていたメモリがほかの他の変数を使用するために自由であることを通知しますか?言い換えれば、すでに利用可能なものがある間に、TclはOSからより多くのメモリを引き上げることにはなりません。 –

+0

@MadhurKashyapループでコードを実行し、OSメモリモニタを調べることで、それを証明できます。全体のメモリ使用量は一定であるため、OSの観点からは明らかに余分なメモリが使用されていないため、メモリを再利用する必要があります。 –

答えて

1

背景情報: Tclの言語モデルは、すべての値が文字列であるということです。厳密には、実装レベルではすべての値が正式にサブタイプの文字列と値が参照渡しされ、参照は不変(したがって書き込まれるときにコピーされます)は共有されます。 Tclの内部では、が非常にという厳密な解釈を受けていますが、その詳細は通常はスクリプトから完全に隠されていますが、非共有の値は書き込み可能です。あなたはパフォーマンスを最適化したり、そうでなくても対処するまで、このようなことを考えるべきではありません。

そう...

帰結:その辞書への最後の参照がなくなったとき辞書を実装するために使用されるメモリは自動的に回収されます。これは、リストや大きな文字列と同じです。 (まあ、小さな文字列や数値、あまりにも、彼らは通常、大したことではないです。)

だから、私はこれを行う場合:その後、メモリはまだdb2変数として割り当てられている

set db [dict create big "bigger" biggest "even more"] 
set db2 $db 
unset db 

が保持している

参照。 unset dbset db {}または set db [dict create]に置き換えると、ほぼ同じ効果が得られます。その元の辞書はまだぶら下がっています。しかし、 最後にの参照がなくなると(別の辞書やリストの内部からさえも)、メモリが整理されます。

はい、正確な例では、メモリは解放されています。

while true { 
    set db [dict create] 
    dict set db key1 value1 
    dict set db key2 value2 
    set db [dict create] 
} 

とOSがプロセスのメモリ使用量は、CPU使用率がCPUコアの(近くに)100%であっても、静的なものであると考えていることを見て:私たちは、このループを実行することにより、これを証明することができます。メモリが漏れた場合、になります! (このループにlappend save $dbを追加することで、これが合理的なテストであることを確認することができ、メモリ使用量が急速に増加するのを見て、それが実際に最悪のメモリを犠牲にしていれば、種類...)

+0

Tclは通常OSにメモリを返しませんが、それは実際には大したことではありません。ほとんどの正常に動作しているプロセスは、必要なメモリの量が制限されており、必要に応じてページングを使用してOSを正常に管理できます。 –

+0

Tclは、オブジェクトの割り当てにmalloc()/ free()を使用します。それは、OSが解放されたメモリを見ているかどうかによって、OSによって異なります。 Tclメモリの使用状況を詳細に分析したい場合は、 'memory'コマンドを有効にするTCL_MEM_DEBUGを設定してTclライブラリをコンパイルします(man 3tcl memoryを参照)。 – tcler

関連する問題