Lua ガベージ コレクション


Lua は自動メモリ管理を使用します。 これは、新しく作成したオブジェクトに必要なメモリを割り当てる方法を心配する必要がなく、オブジェクトが使用されなくなった後にオブジェクトによって占有されていたメモリを解放する方法を心配する必要もないことを意味します。

Lua は、ガベージ コレクター を実行して、すべての デッド オブジェクト (つまり、Lua でアクセスできなくなったオブジェクト) を収集し、自動メモリ管理の作業を完了します。文字列、テーブル、ユーザーデータ、関数、スレッド、内部構造など、Lua で使用されるすべてのメモリは自動管理の対象になります。

Lua は増分マークスキャンコレクターを実装しています。 ガベージ コレクター間隔レートとガベージ コレクター ステップ レートという 2 つの数値を使用して、ガベージ コレクション サイクルを制御します。 どちらの数値もパーセント単位で表されます (たとえば、値 100 は内部的に 1 を表します)。

ガベージ コレクターの一時停止率は、新しいサイクルを開始する前にコレクターが待機する必要がある時間を制御します。 この値を増やすと、コレクターの攻撃性が低くなります。 この値が 100 より小さい場合、コレクターは新しいサイクルを開始する前に待機しません。 この値を 200 に設定すると、コレクターは合計メモリ使用量が以前の値の 2 倍に達するまで待機してから、新しいサイクルを開始します。

ガベージ コレクターのステップ比は、メモリ割り当て速度に対するコレクターの動作速度の比率を制御します。 この値を増やすと、コレクターがより積極的になるだけでなく、各増分ステップの長さも長くなります。 この値を 100 未満に設定しないでください。100 未満に設定すると、コレクターの動作が遅くなり、サイクルが完了しなくなります。 デフォルト値は 200 で、コレクタがメモリ割り当ての「2 倍」速く動作することを意味します。

ステップ乗数を非常に大きな数値 (プログラムが使用する可能性のあるバイト数より 10% 大きい値) に設定すると、コレクターはストップ ザ ワールド コレクターのように動作します。 次に、一時停止率を 200 に設定すると、コレクターは Lua の過去のバージョンと同じように動作します。Lua が使用するメモリを 2 倍にするたびに、完全なコレクションが実行されます。


ガベージコレクター関数

Lua は、自動メモリ管理を制御する関数 collectgarbage ([opt [, arg]]) を提供します:

  • collectgarbage("collect"): 完全なガベージコレクションサイクルを実行します。 。パラメーター opt を通じて、別の関数セットが提供されます:

  • collectgarbage("count"): Lua によって使用される合計メモリを K バイト単位で返します。 この値には小数部分があるため、1024 を掛けるだけで、Lua によって使用される正確なバイト数が得られます (オーバーフローを除く)。

  • collectgarbage("restart"): ガベージコレクターの自動動作を再開します。

  • collectgarbage("setpause"): arg をコレクターの一時停止レートに設定します (§2.5 を参照)。 インターバルレートの前回の値を返します。

  • collectgarbage("setstepmul"): ステップ倍率の前の値を返します。

  • collectgarbage("step"): ガベージコレクターをシングルステップで実行します。 ステップの「サイズ」は arg によって制御されます。 0 が渡されると、コレクターは (分割不可能な) 1 ステップずつ進みます。 ゼロ以外の値を渡すと、コレクタは、これらの多数 (K バイト) のメモリを割り当てる Lua の作業と同等の作業を実行します。 コレクターがループを終了する場合は true を返します。

  • collectgarbage("stop"): ガベージコレクターを停止します。 コレクターは、restart を呼び出す前の明示的な呼び出しに対してのみ実行されます。

以下は簡単なガベージコレクションの例を示しています:

mytable = {"apple", "orange", "banana"}

print(collectgarbage("count"))

mytable = nil

print(collectgarbage("count"))

print(collectgarbage("collect"))

print(collectgarbage("count"))

上記のプログラムを実行すると、出力結果は次のようになります(メモリ使用量の変化に注意してください):

20.9560546875
20.9853515625
0
19.4111328125