Luaリファレンス 要注意点 ~ガベージコレクト~

弱いテーブル(ガベージコレクトされやすいテーブル

  • 通常、これらの機能が使われることはありません。
    しかし、非常に大きなデータオブジェクトをテーブルに格納し、
    これを途中で消したい場合などは、利用する機械があるかもしれません。
  • 変数をnilにするのが基本ですが、それだけでは駄目(というかやり難い)なこともあります。 特に以下のように、テーブルのキーとして利用されている場合です。
    a = {}
    key = {}
    
    a[key] = 3
    
    key = {} -- keyがここで新たに代入されたので、 a[key]の値は不要になっているかもしれないが、Lua自身では感知できない。
    
    a[key] = 4
    collectgarbage()    -- ガベージコレクションを実行
    
    for k, v in pairs(a) do
        print(k, v)
    end
    
    デフォルトでは、途中でkeyが上書きされているからといっても、aのキーとして利用されているので、
    勝手に1つ目のa[key]がガベージコレクトの対象となったりはしません。

  • しかし、これをガベージコレクトの対象としたいような場合、
    __modeというキー持ったメタテーブルを、テーブルにセットします。

    対象のテーブルのメタテーブルに __mode = "k" ならキーが、 __mode = "v"なら値が 、__mode = "kv"なら両方が、ガベージコレクトの対象となります。
    a = {}
    b = {__mode = "k"} -- このメタテーブルをセットされた場合、そのテーブルのキーが、他から参照されていないオブジェクトの場合のみ、ガベージコレクトの対象とする。という意味。
    setmetatable(a, b)
    key = {}
    
    a[key] = 3
    
    key = {}
    a[key] = 4
    
    collectgarbage()    -- ガベージコレクションを実行
     
    for k, v in pairs(a) do
       print(k, v)
    end
    

  • なお、キーが数値や文字列の場合は、決してガベージコレクトの対象にならないので注意。あくまでオブジェクト(テーブル、ユーザー定義)のみ。

トップ   差分 履歴 リロード   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2014-08-20 (水) 00:00:00