2012-02-01 19 views
3

開発のためにLuaでcocos2d-xを使用しています。最近、私はInstrumentsを使用し、放棄されたメモリ量を発見しました: cocos2d-xは、独自の自動解放プール内のオブジェクトに対してリリースを実行しますが、私はまだLuaからの参照を持っています。 これらの参照はいつ作成されるのですか? スペースに残されたメモリ割り当てが放棄されないように、そのメモリを解放する必要があります。私の心に来る唯一の事は、ルアポインタnilを見ないためにいくつかのルアデバッガを使用することです。Luaで放棄されたメモリリークを追跡する方法は?

ポインタを保持するLuaリファレンスがわかっていれば、手動で解放することができました。

+0

Cocos2D-Xがオブジェクトを単独でリリースできる場合、それらのオブジェクトへの直接参照をLuaコードに与えるべきではありません。あるいは、Luaがそれらのオブジェクトにアクセスするとき、Luaがそれらを終了するまでそれらを解放しないようにCocos2D-Xに知らせる何らかの方法が必要です。既に問題が解決していない場合は、問題を後方に解決しようとしています。 –

+0

あなたはそうです。私はすでにこれを行うコードを受け取りました。そして、私はluaレベルからオブジェクトをリリースし、それらを解放するためのcocos2d-xトリガを与えるようにしました。今私はいくつかの記憶を放棄しており、効率的にしたいと思っています。 –

答えて

2

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

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

この記事の残りの部分では、このコードが存在し、正しく機能すると仮定します。これを自分で確認する必要があります。その仮定を考える

は、何を見ていることは、二つの理由の1のために起こる:

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

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

ケース#2を扱うことは困難です。責任を負うのはルアコードの責任です。それは物を参照する必要があるときに参照を格納し、その後それらの参照を忘れてしまいます。これによって、非ローカル変数に値を格納しないでください(また、「非ローカル」では、ネストされた関数定義によって使用されるローカルを避けることも意味します)。

これらの参照がまだ存在する場所を見つける方法はありません。結局のところ、ルア値は必ずしも名前を持つ必要はありません。また、Luaは実際にはlua_Stateのすべての変数を繰り返し処理する方法を提供していません。たとえあったとしても、があります。確かにこれらの参照を単に空白にする方法はありません。結局のところ、ルアコードはまだタッチそれらをすることができます。あなたがそれらを隠してしまった場合、それらのオブジェクトと会話しようとすると、Luaコードはクラッシュします。だから、たとえあなたが望んだことをすることができたとしても、それは逆効果です。

私はこれに対処するための3つの方法のいずれかを示唆している:あなたのスクリプトで

  1. 運動規律を。すべての非LUAオブジェクトが格納されている場所を確認してください。これらのオブジェクトがリリースされるべきときにリリースされていることを確認してください。これらの外部オブジェクトをどこに置くかを知り、それらが時間通りにリリースされることを確認します。 「リリースされました」とは、単にその値をnilで上書きすることを意味します。

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

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

+0

アドバイスをいただきありがとうございます。彼らは次のアプローチで考慮されます。現時点では、私は既存のluaソースからプロジェクトを回復する必要があるので、参照を保持する可能なポインタを調べるには良いデバッガが必要です。このようなことが起こる直前に、あなたの "ルアスマートポインター"に代わるものを作ることは良いことかもしれません。 –

0

私はこの問題を偶然見つけました。

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

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

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

関連する問題