4

私は開発のためにLuaでcocos2d-xを使用しています。最近、Instrumentsを使用して、放棄されたメモリを発見しました。cocos2d-xは、独自の自動解放プール内のオブジェクトに対して解放を実行しますが、Luaからの参照がまだあります。それらの参照がいつ行われるかを理解する方法は?スペースに残された放棄されたメモリ割り当てを回避するために、そのメモリを解放する必要があります。私の頭に浮かぶ唯一のことは、nilLuaポインターではなく、Luaデバッガーを使用して処理することです。

どのLua参照がポインターを保持しているのかしかわからない場合は、手動で解放できます。

4

2 に答える 2

3

あなたの質問は少し奇妙な言葉でした。しかし、私が理解しているように、Luaスクリプトには、外部コードで割り当てられたオブジェクトへの参照があります。そして、Luaがこれらの参照を持っている限り、外部コードはそれらのリソースを解放しません。そして、あなたはそれらの資源が解放されるべきであると信じています。

最初に確認する必要があるのは、Luaインターフェースコードがメタメソッドを使用して参照を適切にクリーンアップすることです。つまり、Luaがオブジェクト参照で終了すると、Luaがオブジェクトで終了した__gcことを外部コードに通知するメタメソッドがアタッチされます()。

この投稿の残りの部分では、このコードが存在し、正しく機能していると想定します。これを自分で確認する必要があります。

その仮定を考えると、あなたが見ていることは、次の2つの理由のいずれかで起こります。

  1. Luaコードはすべての参照の使用を終了しましたが、まだクリーンアップされていません。これは、Luaスクリプトがローカル変数、グローバル変数などの参照を持たなくなったことを意味します。この場合、Luaのガベージコレクターはまだ実行されておらず、クリーンアップされていません。したがって、でそれを行う必要がありますlua_gc(L, LUA_GCCOLLECT, 0);。この場合、この関数を実行した後、Luaからのすべての参照がクリーンアップされているはずです。

  2. Luaコードには、まだ潜んでいる外部オブジェクトへのアクティブな参照があります。

ケース#2に対処することは困難です。責任を負うのはLuaコードの責任です。何かを参照する必要があるときに参照を保存し、後でそれらの参照を忘れる必要があります。つまり、値を非ローカル変数に格納しないことを意味します(また、「非ローカル」とは、ネストされた関数定義で使用されるローカルを回避することも意味します)。

それらの参照がまだ存在する場所を見つける手段はありません。結局のところ、Luaの値には必ずしも名前が付いているわけではありません。また、Luaは、で可能なすべての変数を反復処理する方法を実際には提供していませんlua_State。あったとしても、それらの参照を単に空白にする手段は確かにありません。結局のところ、Luaコードはまだそれらに触れることができます。それらをブランクにすると、Luaコードがそれらのオブジェクトと通信しようとしたときにクラッシュします。ですから、あなたがやりたいことができたとしても、それは逆効果になります。

これに対処するための3つの方法のいずれかをお勧めします。

  1. スクリプティングで規律を行使します。Lua以外のすべてのオブジェクトがどこに保存されているかを確認してください。これらのオブジェクトが必要なときにリリースされていることを確認してください。これらの外部オブジェクトをどこに配置するかを把握し、それらが時間どおりにリリースされることを確認してください。「リリースされた」とは、単にそれらの値を。で上書きすることを意味しますnil

  2. スクリプトとソースコードの間に絶縁層を構築します。LuaにCocos2D-Xオブジェクトへのポインターを直接与えるのではなく、Cocos2D-Xオブジェクトへの参照を含む可能性のある特別なオブジェクトへのポインターを与えます。このように、このコントロールオブジェクトに参照を削除するように指示することで、これらのオブジェクトがいつ解放されるかを直接制御できます。Luaが空のコントロールオブジェクトを呼び出すと、関数は...無害なものを返します(クラッシュしないようにするため)。明らかに、Luaはそれが有効なコントロールオブジェクトであるかどうかを確認する関数を持っている必要があります。

  3. Luaでやりたいことは何でもしますが、リソースを解放するときは、Luaの状態全体を破棄します。現在の方法は非常にきめ細かいものです。Luaはいくつかのリソースを作成し、Luaはそれらがいつなくなるかを決定します。より厳密なリソース管理スキームは、Luaスクリプトがいくつかのリソースと参照リソースをロードすることです。しかし、それらのリソースをすべて破壊するときは、あなた自身だけlua_closeですlua_State。これにより、すべての参照が解放され、それらのリソースが解放されます。問題が解決しました。

于 2012-02-01T17:43:59.920 に答える
0

私もこの問題に遭遇しました。

残念ながら、Cocos2d-xは、Luaスクリプトエンジンがオブジェクトへの参照を持っているにもかかわらず、CCObjectを破棄する可能性があります。バインディングは完全ではないようです。

これをテストするには、静的パッケージにCCNodeを作成し、シーンに別のCCNodeを追加してから削除し(クリーンアップをトリガーして)、フレームの更新を待ちます。有効なlua参照があるにもかかわらず、元のCCNodeオブジェクトは失われ、Luaでそのオブジェクトのメソッドを呼び出そうとすると、オブジェクト〜= nilにもかかわらず、エラーがスローされます。

これを回避するには、CCMutableArray_CCObject__オブジェクトを作成し、それにCCObjectsを追加します。これにより、これらのオブジェクトの参照カウントが増加し、CCMutableArray_CCObject__はlua参照もgcされない限りgcされません。

于 2013-06-04T20:05:26.700 に答える