82


2

Actionscript 3を使用したByteArrayのアンロード

ActionScript 3を使用してメモリから `ByteArray`を強制的にアンロードする方法を教えてください。

私は以下を試しました:

// First non-working solution
byteArray.length = 0;
byteArray = new ByteArray();

// Second non-working solution
for ( var i:int=0; i < byteArray.length; i++ ) {
    byteArray[i] = null;
}

8 Answer


33


あなたが心配することは何もないと思います。 `System.totalMemory`が落ちたら、リラックスできます。 新しく解放されたメモリを再利用しないのは、OSである可能性があります(次回Flash Playerがより多くのメモリを要求する予定です)。

メモリを多用する他のことをしてみてください。FlashPlayerに割り当てられたメモリが減少し、代わりに他のプロセスに使用されることに気付くでしょう。

私が理解したように、現代のOSのメモリ管理は各プロセスに割り当てられた量、あるいは割り当てられた総量さえ見るという観点から直観的ではありません。

私のMacを5分間使用したとき、3 GBのRAMの95%が使用されています。 それはOSがメモリを扱う方法です。

他の場所で必要とされていない限り、終了したプロセスでもメモリが割り当てられています(これにより、次回の起動が早くなります)。


24


(私はこれについて前向きではありませんが…​)

AS3は非決定論的ガベージコレクションを使用します。 つまり、参照されていないメモリは、ランタイムがそのように感じたときはいつでも解放されます(通常、実行する理由がない限り、実行するのが高価な操作なので)。 これは、最近のほとんどのガベージコレクション言語(C#やJavaなど)でも同じ方法です。

byteArray`が指すメモリまたは配列自体の中の項目への参照が他にないと仮定すると、 byteArray`が宣言されているスコープを終了した後のある時点でメモリは解放されます。

ガベージコレクションを強制することはできますが、実際にはそうしないでください。 もしそうなら、テストのためだけにそれをしてください…​ 本番環境でそれを行うと、手助けをするよりはるかにパフォーマンスが低下します。

GCを強制するには、(はい、2回)試してください。

flash.system.System.gc();
flash.system.System.gc();


19


この記事を見てください

IANAのActionScriptプログラマー、しかし私が感じているのは、ガベージコレクタが必要なときに実行されない可能性があるからです。

したがってhttp://www.craftymind.com/2008/04/09/kick-starting-the-garbage-collector-in-actionscript-3-with-air/

それで私は彼らのコレクションコードを試してみてそれが助けになるかどうかを見ることをお勧め

private var gcCount:int;プライベート関数startGCCycle():void {gcCount = 0; addEventListener(Event.ENTER_FRAME、doGC);プライベート関数doGC(evt:Event):void {flash.system.System.gc();} if(gcCount> 1){removeEventListener(Event.ENTER_FRAME、doGC); setTimeout(lastGC、40);プライベート関数lastGC():void {flash.system.System.gc();} }


15


残念ながら、_Flash / actionscript_でのメモリ管理に関しては、できることはあまりありません。 ActionScriptは使いやすいように設計されています(したがって、メモリ管理について心配する必要はありません)。

以下は回避策です、 `ByteArray`変数を作成する代わりにこれを試してください。

var byteObject:Object = new Object();

byteObject.byteArray = new ByteArray();

...

//Then when you are finished delete the variable from byteObject
delete byteObject.byteArray;

byteArray`が byteObject`の動的プロパティであるところで、あなたはそれに割り当てられたメモリを解放することができます。


15


私はあなたがあなた自身の質問に答えたと信じています…​

`System.totalMemory`は、割り当てられていない、「使用されている」メモリの総量を示します。 アプリケーションが20MBしか使用していない可能性があるのは正確ですが、将来の割り当てには5MBの空き容量があります。

アドビのドキュメントがメモリ管理の方法を明確にするかどうかはわかりませんが…


10


したがって、MySQLから20MBをロードした場合、タスクマネージャではアプリケーションのRAMが約25MB上がることになります。 その後、接続を閉じてByteArrayを破棄しようとすると、RAMが解放されることはありません。 しかし、System.totalMemoryを使用すると、フラッシュプレーヤーはメモリが解放されていることを示しますが、そうではありません。

FlashプレーヤーはJavaのようなことをしてヒープスペースを予約し、アプリが終了するまでそれを解放しませんか? _

あなたはAVM2のGCが楽観的であり、それが独自の神秘的な方法で動作するようになるでしょう。 したがって、Javaのように動作し、ヒープスペースを予約しようとします。ただし、十分な長さにして、かなりのメモリを消費している他の操作を開始すると、以前のスペースは解放されます。 あなたはあなたのアプリの上で実行されているいくつかのテストで一晩プロファイラーを使用してこれを見ることができます。


9


したがって、MySQLから20MBをロードした場合、タスクマネージャではアプリケーションのRAMが約25MB上がることになります。 その後、接続を閉じてByteArrayを破棄しようとすると、RAMが解放されることはありません。 しかし、System.totalMemoryを使用すると、フラッシュプレーヤーはメモリが解放されていることを示しますが、そうではありません。 _

プレイヤーはメモリを「解放」しています。 ウィンドウを最小化して元に戻すと、memeoryがSystem.totalMemoryに表示されるものに非常に近くなっていることがわかります。

FlexBuilderのプロファイリングツールを使用して、本当にメモリリークが発生しているかどうかを確認することもできます。