web-dev-qa-db-ja.com

AS3でガベージコレクションを強制しますか?

完全なガベージコレクションをActionScript3.0でプログラムで強制的に実行することは可能ですか?

EventListenersを使用して多数のDisplayオブジェクトを作成し、一部のDOが削除され、一部のeventListenersがトリガーされて削除されたとしましょう...ガベージコレクションを強制的に実行し、すべてを収集する方法はありますか?収集できますか?

18
defmeta

はい、可能ですが、一般的には悪い考えです。 GCは、実行するのに適した時期を必要以上に把握している必要があります。500MBのメモリを使用したばかりで、できるだけ早く元に戻す必要があるなどの非常に特殊な場合を除いて、GCを呼び出さないでください。あなた自身。

Flash 10には、呼び出すことができるSystem.gc()メソッドがあります(ただし、呼び出さないでください。上記を参照してください)。System.gc()は、Flashプレーヤー10以降のデバッグバージョンでのみ機能することに注意してください。

Flash 9には、奇妙なLocalConnectionコマンドを介して強制するサポートされていない方法がありますが、すべてのバージョンで機能するとは限りません。 GrantSkinnerによる この投稿 を参照してください。

25
davr

収集するのが「比較的良い瞬間」である可能性があることをGCに通知するための新しいAPIがあります。

System.pauseForGCIfCollectionImminent については、AdobeAPIのドキュメントを参照してください。

また、これは Adobeブログ投稿 Playerバージョン11でメソッドが導入された直後から

このメソッドは「差し迫った」引数を取ります。基本的に、最後のコレクション以降にアクティビティ(現在はバイト割り当てで測定)があまりない場合でも、コレクターを本当に実行したい場合は、少ない数(0.0に近い)をフィードし、多数(0.0に近い)をフィードします。 1.0に近い)とにかくコレクションが発生するポイントにすでに近づいた場合にのみ、コレクションの一時停止を発生させたい場合。

ここでの動機は、たとえばGCが発生するポイントを少しシフトしたいゲーム。プレイヤーがレベルの探索を開始してから2秒後ではなく、ゲームのレベルの変更中にGCを実行します。

1つの非常に重要な詳細:この新しいAPIは、リリースとデバッガーの両方のフラッシュランタイムでサポートされています。これにより、System.gc()を呼び出すよりも優れています。

15
pnkfelix

現在リリースされているすべてのバージョンで、System.gc()は、FlashプレーヤーとADL(AIRアプリのデバッグ環境)のデバッグバージョンでのみ機能します。 Flash Player 10ベータ版は現在、すべてのフレーバーで機能します。

私はDavrに同意します、それは悪い考えです。ランタイムは通常、あなたよりも優れたアイデアを持っています。

さらに、ガベージコレクターの動作の詳細は、FlashPlayerのバージョン間で変更される可能性のある実装の詳細です。したがって、現在うまく機能しているものが、将来うまく機能するという保証はありません。

8
Marc Hughes
try {
    new LocalConnection().connect('foo');
    new LocalConnection().connect('foo');
} catch (e:*){
    trace("Forcing Garbage Collection :"+e.toString());
}
3
Sean

他の人が言ったように:手動でGCを試みないでください、ハックがありますが、それは安全ではありません。

可能であればリサイクルオブジェクトを試してみてください-多くのメモリを節約できます。

これは、たとえばBitmapDatas(クリアして再利用)、パーティクル(表示から削除して再利用)に適用できます。

3
Philippe

手動でGCを実行してはいけないというコメントがあります。私はC++での手動メモリ管理に慣れており、GCよりもsharedptrの方が好きですが、とにかく。

GC以外の解決策が見つからない特定のケースがあります。考慮してください:私はDataCacheクラスを持っています、それが機能する方法は、データを更新/受信するときに更新されたイベントを送信する特定のメソッド呼び出しの結果オブジェクトを保持することです。キャッシュを更新する方法は、キャッシュからすべての結果をクリーンアップしてイベントを送信することです。これにより、残りのリスナーはデータを再要求し、スコープ外になったリスナーは再要求しないで、不要な結果をクリーンアップします。しかし、どうやら、「もう一度データを尋ねる」イベントを送信する前に、GCがすぐにクリーンアップされるのを待ってまだぶら下がっているすべてのリスナーを強制できない場合、それらのぶら下がっているリスナーは不必要にデータを再度要求します。したがって、AS3にはデストラクタがないため、EventListenerを削除できないため、GCにぶら下がっているリスナーがないことを確認する以外に、別の簡単な解決策を見つけることはできません。

(編集)その上、たとえばmxmlで設定されたバインディングにremoveEventListenerを使用することはできません(remoteobjを処理するカスタムDataCacherクラスを使用)

<mx:DataGrid id="mygrid" dataProvider="{DataCacher.instance().result('method').data}" ... />

このデータグリッドを含むポップアップウィンドウを閉じると、バインディングが破棄されることが予想されます。どうやら彼らはずっと生き続けています。うーん、最後の参照が削除されているため、GCのオブジェクトがマークであるときに、オブジェクトからすべてのバインディング(イベントリスナーを意味する)を曲げて破棄しないでください。それは私にとって問題をちょっと解決するでしょう。

少なくともそういうわけで、私はまだFlexの初心者なので、どんな考えでもいただければ幸いです。

3
FredV

リサイクルは本当に役に立ちません。 500msごとに同じjpgを繰り返しロードするローダーを1つ使用しました。タスクマネージャは、メモリのノンストップの増加を報告しました。

ここで実証済みのソリューション。

http://simplistika.com/as3-garbage-collection/

0
jaredy

必要に応じて、ガルガベコレクターに電話すると便利かもしれません...だから、いつ、どのように行うか注意する必要がありますが、必要な場合があることは間違いありません。

たとえば、モジュール式のアプリがある場合、あるビューから別のビューに変更すると、削除されたすべてのオブジェクトが大量のメモリを表す可能性があり、可能な限り高速に使用できるようにする必要があります。破棄する変数と参照。

0