1. ホーム
  2. スクリプト・コラム
  3. ルア

Luaのガベージコレクション機構をわかりやすく解説します。

2022-02-10 10:47:41

 Luaでは、特定のアルゴリズムに組み込まれたガベージコレクションに基づく自動的なメモリ管理を採用しています。自動メモリ管理は、開発者としては、結果として

  •     オブジェクトのメモリ割り当てを気にする必要がありません。
  •     不要になったら解放する必要がなく、nilに設定することができる。

Luaは、時々死んで収集するオブジェクトを使用する場合、Luaプログラム内からガベージコレクタにアクセスすることはなくなりました。

テーブル、ユーザーデータ、関数、スレッド、文字列など、すべてのオブジェクトは、自動的なメモリ管理の対象となります。Luaはインクリメンタルマーカーを使用し、ガベージコレクションサイクル、すなわちガベージコレクション休止と、コレクターを途中までクリアするガベージコレクタステップの2つの数値を使って制御しています。これらの数値の単位はパーセントで、100という値は常に1と等しくなります。
ガベージコレクションの一時停止

ガベージコレクション休止は、Luaの自動メモリ管理によって再び呼び出される前に、ガベージコレクタが待機する時間を制御するために使用されます。値が100以下の場合、Luaでは次のサイクルが待機されません。同様に高い値を設定すると、ガベージコレクタの動作が遅くなり、積極的でなくなります。200は、新しいサイクルを開始する前に、使用中の総メモリの2倍の時間、収集が待機することを意味します。したがって、アプリケーションの性質や速度によっては、Luaアプリケーションで最高のパフォーマンスを得るために、この値を変更する必要がある場合があります。
ガベージコレクタのステップを半分の労力で

このステップ倍率は、Luaプログラムにおけるガベージコレクションのメモリ割り当ての相対的な速度を制御します。ステップの値を大きくすると、ガベージコレクタはより積極的になり、またガベージコレクションの各増分ステップのステップサイズも大きくなります。100以下の値は、ガベージコレクタがそのサイクルを完了しないことを避ける結果になることが多く、一般的に好まれません。デフォルト値は200で、これはガベージコレクタがメモリ割り当ての2倍の速度で実行されることを意味します。
ガベージコレクタ機能

開発者としては、Luaにメモリ管理を自動化させたいという歴史があります。これにはいくつかの方法があります。

  •     collectgarbage("collect"): ガベージコレクションの全サイクルを実行します。
  •     collectgarbage("count")。現在使用中のプログラムメモリの量をキロバイト単位で返す
  •     collectgarbage("restart"): ガベージコレクタが停止している場合、再スタートします。
  •     collectgarbage("setpause")。ガベージコレクタの一時停止変数に、第2引数で与えられた値を100で割った値を設定します。議論の上のビットとして使用されます。
  •     collectgarbage("setstepmul"): 第2引数で与えられた変数を100で割った値をガベージステップ倍率に設定します。議論の上のビットとして使用されます。
  •     collectgarbage("step"): ガベージコレクションステップを実行する。第2引数が大きければ大きいほど、ステップも大きくなる。ガベージコレクションは、トリガーされたステップがガベージコレクションサイクルの最後のステップである場合、trueを返します。
  •     collectgarbage("stop")。ガベージコレクタが動作している場合、それを停止する。

ガベージコレクタを例として、簡単な使用例を以下に示します。

コピーコード コードは以下の通りです。
mytable = {"apple", "orange", "banana"}

print(collectgarbage("count"))

mytable = nil

print(collectgarbage("count"))

print(collectgarbage("collect"))

print(collectgarbage("count"))

上記のプログラムを実行すると、次のような出力が得られます。なお、Luaの自動メモリ管理機能もOSによって異なる可能性があるので、このような結果は異なるでしょう。

コピーコード コードは以下の通りです。
20.9560546875
20.9853515625
0
19.4111328125

上記のプログラムでお分かりのように、ガベージコレクションが完了すれば、メモリ使用量の削減の両方が可能です。しかし、どちらか一方を呼び出すことが必須というわけではありません。呼び出しを行わなくても、あらかじめ決められた時間が経過した後の段階で、Luaインタープリタによって自動的に実行されるのです。

もちろん、ガベージコレクタを使用する必要がある場合は、これらの関数の動作を変更することができます。これらの機能は、開発者が複雑な状況を処理するための、ちょっとした追加機能を提供するものです。プログラムの実行に必要なメモリの種類によって、この機能は使われたり使われなかったりします。しかし、アプリケーションでのメモリ使用量や、プログラム自体で、デプロイ後の結果に対する不要なチェックを回避することができます。