ActionScript 3.0 でフル ガベージ コレクションの実行をプログラムで強制することはできますか?
eventListeners を使用して一連の Display オブジェクトを作成し、一部の DO が削除され、一部の eventListeners がトリガーされて削除されたなどとしましょう...ガベージ コレクションを強制的に実行してすべてを収集する方法はありますか?収集可能ですか?
ActionScript 3.0 でフル ガベージ コレクションの実行をプログラムで強制することはできますか?
eventListeners を使用して一連の Display オブジェクトを作成し、一部の DO が削除され、一部の eventListeners がトリガーされて削除されたなどとしましょう...ガベージ コレクションを強制的に実行してすべてを収集する方法はありますか?収集可能ですか?
はい、可能ですが、一般的には悪い考えです。GC は、いつ実行するのが適切なのかについて、本来よりも優れた考えを持っている必要があります。また、500MB のメモリを使用したばかりで、できるだけ早く戻す必要があるなどの非常に特殊なケースを除いて、GC を呼び出すべきではありません。あなた自身。
Flash 10 には、System.gc()
呼び出すことができるメソッドがあります (上記を参照してください)。System.gc() は Flash Player 10 以降のデバッグ バージョンでのみ機能することに注意してください。
Flash 9 では、奇妙な LocalConnection コマンドを介して強制するサポートされていない方法がありますが、すべてのバージョンで機能するとは限りません。Grant Skinner によるこの投稿を参照してください。
収集するのに「比較的良い瞬間」である可能性があることを GC に伝えるための新しい API があります。
System.pauseForGCIfCollectionImminentの Adobe API ドキュメントを参照してください。
また、Player バージョン 11 でメソッドが導入された直後のこのAdobe ブログ投稿
このメソッドは「imminence」引数を取ります。基本的に、コレクターを本当に実行したい場合は、前回の収集以降に多くのアクティビティ (現在は割り当てられたバイト数で測定) がなくても、低い数値 (ほぼ 0.0) をフィードします。 1.0 付近) とにかくコレクションが発生するポイントにすでに近づいている場合にのみ、コレクションの一時停止を発生させたい場合。
ここでの動機は、GC が発生するポイントを少しずらしたいゲームなどの状況です。たとえば、プレイヤーがレベルを探索し始めてから 2 秒後ではなく、ゲームのレベルの変更中に GC を実行します。
1 つの非常に重要な詳細: この新しい API は、Release と Debugger Flash ランタイムの両方でサポートされています。これにより、System.gc() を呼び出すよりも優れています。
現在リリースされているすべてのバージョンで、System.gc() は Flash Player のデバッグ バージョンと ADL (AIR アプリのデバッグ環境) でのみ機能します。Flash Player 10 ベータ版は現在、すべてのフレーバーで動作します。
私はDavrに同意します。それは悪い考えです。ランタイムは通常、あなたよりも優れたアイデアを持っています。
さらに、ガベージ コレクターの動作の詳細は、Flash Player のバージョン間で変更される可能性のある実装の詳細です。したがって、現在うまく機能しているものは、将来もうまく機能するという保証はありません。
他の人が言ったように:手動でGCを試みないでください、ハックがありますが、それは安全ではありません。
可能な場合は、オブジェクトのリサイクルを試してください。多くのメモリを節約できます。
これは、たとえばBitmapDatas(クリアして再利用)、パーティクル(表示から削除して再利用)に適用できます。
try {
new LocalConnection().connect('foo');
new LocalConnection().connect('foo');
} catch (e:*){
trace("Forcing Garbage Collection :"+e.toString());
}
手動で GC を行うべきではないというコメントがあります。私は C++ で手動のメモリ管理に慣れており、GC よりも sharedptr を好みますが、いずれにせよ。
GC を実行する以外に解決策が見つからないという特定のケースがあります。考慮してください: 私は DataCache クラスを持っています。それが機能する方法は、データの更新/受信時に更新されたイベントを送信する特定のメソッド呼び出しの結果オブジェクトを保持することです。キャッシュを更新する方法は、そこからすべての結果を消去してイベントを送信することです。これにより、残りのリスナーがデータを再要求し、範囲外になったリスナーは再要求してはならず、不要な結果が消去されます。しかし、どうやら、GC がクリーンアップされるのを待っているすべてのリスナーを、「データをもう一度尋ねる」イベントを送信する直前に強制できない場合、これらのぶら下がっているリスナーは、不必要にデータを再度要求します。AS3 にはデストラクタがないため、EventListener を削除できないので、削除できます。
(編集)その上、たとえば、mxmlでセットアップされたバインディングにremoveEventListenerを使用することはできません(remoteobjを処理するカスタムDataCacherクラスを使用)
<mx:DataGrid id="mygrid" dataProvider="{DataCacher.instance().result('method').data}" ... />
このデータグリッドを含むポップアップ ウィンドウが閉じられると、バインドが破棄されることが予想されます。どうやら彼らは生き続けているようです。うーん、最後の参照が削除されるため、オブジェクトが GC 用にマークされているときに、オブジェクトからすべてのバインディング (イベントリスナーを意味する) を flex destroy するべきではありません。それはちょっと問題を解決するでしょう。
少なくともそれが私が考える理由です。私はまだ Flex の初心者なので、どんな考えでもいただければ幸いです。
リサイクルはあまり役に立ちません。500ms ごとに同じ jpg を繰り返しロードする 1 つのローダーを使用しました。タスク マネージャーは引き続き、メモリの増加が止まらないことを報告しました。
ここで実証済みのソリューション。
やむを得ない場合は、ガベージコレクターに電話すると便利かもしれません...なので、方法とタイミングには注意が必要ですが、必要な場合があることは間違いありません。
たとえば、モジュール式のアプリを使用している場合、あるビューから別のビューに変更すると、削除されたすべてのオブジェクトが大量のメモリを表す可能性があり、可能な限り高速に使用できるようにする必要があります。あなたが処分している変数と参照。