2009-06-21 1 views
4

私は約6年間ActionScriptでプログラミングしてきましたが、AS3が出てくるまで「ガベージコレクション」という言葉を聞いたことはありませんでした。なぜ今はそれを心配しなくてはならないのですか?そして、それは正確に何ですか?私が読んだことや聞いたことから、メモリ管理/リークなどと関係しています。さらにのように、パフォーマンスとは関係がありません。ガベージコレクションとは何か、ActionScript 3.0ではどのようにしますか?

私は最近、私のアーティストの友人のサイトを立ち上げました。これはAS3で行われました。私はそれが多くのリソースを消費することに気付いています。明らかに、これは私が改善したいことです。私はそれが起こっているガベージコレクションがないという事実と関係があると思いますか?残念ながら、私はそれが何であるかをうまく突き止める必要があると感じ、AS3で具体的にそれをやり遂げる方法を知る必要があると感じるので、それに関してどこから始めるべきかについては少しも考えていません。好奇心のために

、ここにURLです:http://www.jeffperrott.com

答えて

0

私はAP3の実装については何も知らない、誰かがこれを掲示しなければならない:)

基本的に

http://en.wikipedia.org/wiki/Garbage_collection_(computer_science)

、あなたが仕事データへのポインタ(井戸、参照)範囲外になる参照は削除されます。参照がデータを指していない場合、データはガベージコレクションのマークが付けられます。あなたのGBスレッド(プロセスまたはデーモン)は、マークされたデータの割り当てに使用されたすべてのリソースを時に解放します。

0

通常、開発者は、アプリケーションデータをメモリに格納するための領域を作成したり、アプリケーションの実行後にメモリを使用しないように手動で処理する必要があります。実行時にGC(ガベージコレクタ)がない場合は、アプリケーション内の変数やオブジェクトの作成やメモリ空間の削除を手動で処理する必要があります。

例として、ネイティブC++があります。 C++プログラマーがアプリケーションで本当に多くをする前に、彼ら自身がメモリを扱う根拠のある仕事をする必要があります。 OSはメモリを要求し、割り当てを追加し、オブジェクトとデータをメモリに追加し、後でオブジェクトとデータを削除し、メモリの割り当てを解除し、クリーンアップして再びOSにリリースします。

GCを使用すると、GCがすべて機能します。あなたが行うことは、メモリを使用する予定のGC(通常はオブジェクトをインスタンス化することによって)に指示し、必要なメモリ量をGCが把握し、OSに要求し、データを割り当て、追加します。その後、アプリケーションがそのオブジェクトをまだ使用しているかどうかを時々チェックします。そうでない場合は、オブジェクトを削除し、割り当てを解除し、クリーンアップしてOSに戻します。これはすべてあなたのために行われるので、プログラマはあなたのプログラムに集中できます。これの例はVB 6.0とC#/ VB.NETです。

編集:これは非常に簡単な説明です。実際にはこれより多くのことが実際にありますが、この回答はここで尋ねられる基本的な質問に答えるべきです。

6

ガベージコレクタは、使用していないメモリをクリーンアップするランタイム(あなたの場合はFlashまたはAIRプレーヤー)の一部です。 ActionScriptには、すべてのスクリプト言語(javascript、perl、rubyなど)のようなガベージコレクションが常にありました。

基本的な考え方は、作成されたすべてのオブジェクトがいくらかのメモリをとり、変数がそれらのオブジェクトを参照し続けるということです。オブジェクトへの参照がなくなるまで、オブジェクトのメモリは利用可能なメモリプールに「解放」されません。ガベージコレクタは、どのオブジェクトに参照があるかを追跡し、さまざまな間隔でゼロ参照を持つ人のメモリを再利用します(つまり、変数を指す変数がないため、コードでも参照できません)。参照がある場合、コードの一部が将来使用することを決定した場合、そのオブジェクトのメモリを再利用することはできません。

プログラムがメモリをリークしているように見える場合は(サイズが安定したり、収縮しないことがあります)、ハッシュや配列、またはその他のコレクションオブジェクトにオブジェクトを配置している可能性があります。このオブジェクトは明らかにコンテンツへの参照を保持しているので、削除されることはありません。

イベントハンドラとしてクロージャを使用することで、ActionScriptでは「リーク」を簡単に作成できます。割り当てられているが決してゼロにならない変数にハンドラーがアクセスできる場合、それらの変数は参照を保持し、それらが指すオブジェクトはイベントハンドラーが登録されている限りガベージコレクションされません。

直接ガベージコレクタを起動
function registerHandler(neverReleased:Object) { 
    ... 
    addEventHandler(function (e:Event) { 
      ... 
     }); 
} 

はほとんど常に悪いことで(TM)で、フラッシュ/ Flexでのガベージコレクタは非常に良いです。最初にあなたのオブジェクトがどこに保持されているかを見つけ出し、それらを解放して、GCがそれ自身のスケジュールで動作するようにします。

circular referencesを除き、この回答の範囲外です。

0

チャドウィックの答えに追加する:あなたaddEventHandler場合は画像に

が、画像がもはや表示されたときに、画像によって占められるメモリは、ガベージコレクタによって回収することはできませんremoverEventHandlerません。

+0

AS3では、イベントリスナーへの弱い参照を作成して、イメージなどをガベージコレクションできるようにすることができます。 –

+0

これはaddEventListenerであり、逆の方法です。イベントをリッスンする関数は、イメージが存在する限り収集されません。 –

+0

あなたは本当に正しいです。私の間違いを指摘してくれてありがとう。 –

2

"new"キーワードを使用してオブジェクトを作成するたびに、あなたはクレームをメモリ[1]にかけています。だから、あなたはvar exampleUint:uint = new uint();と書くことで、あなたが作っているとしましょう。 ActionScriptはコンピュータに "ちょっと...私は4バイトのメモリが必要です"というメッセージが表示されますが、コンピュータは "ok cool、0x7B3208C1のようなメモリアドレスから始まる4バイトを使用します" [2] 。だから、var someString:String = "blah";と言うときは、メモリ内のスペースを要求し、いくつかの情報(この場合は"blah")を入力し、ラベル(この場合はsomeString)を作成し、メモリ内のそのスペースのラベルにbindを付けます。

ラベルはデータ自体に実際には関連付けられていません。データを含むメモリ内のスポットに関連付けられます。それは混乱しているように見えるはずですが、それはある理由のために全体的な意味合いがあります。 ActionScriptのすべてのオブジェクトはreferenceの型です。つまり、オブジェクトにはデータそのものではなく、データの一部のメモリアドレスが含まれています。これは、ラベルがデータ自体に関連付けられるvalueタイプのオブジェクトとは対照的です。値の型の詳細については、ActionScriptにはないので気にしないでください。あなたの目的のために、私はそれを厳密にコントラストに含めています。 OK、混乱していますか?あなたはおそらく、この段落全体が不必要に特定であり、おそらくは不必要であるため、かもしれないので、はあなたの問題と関係があるので、頭の後ろにそれを保持しようとするので、

このラベルが消えた場合(scopeから外れるなど)、someStringというラベルのみが削除されます。したがって、この例ではsomeString = null;と言うと、文字列"blah"は実際にはまだメモリに残っていますが、ラベルsomeStringはその情報を参照していないため、the null objectというメモリアドレスを参照しています。私は、コンピュータに "あなたが[whateverAddress]で始まると主張しているメモリを知っていますか?それで、他の誰かがそのメモリを使うことができるようになりました"。Gabage collectionは、自分で心配することなく、あなたが主張したメモリを再利用する自動プロセスです。ガベージコレクションのない言語では、newには、オブジェクト[3]に関連付けられたメモリを特に解放する補完キーワードがありますが、ActionScriptにはそれがありません。あなたはただの思い出を忘れてしまいます。

他の変数を作成し、そのデータを参照している可能性があります。var someOtherString:String = someString;だから、「ok」と言うだけではありません。someStringというラベルがなくなったので、参照するデータなぜなら、someStringがそのデータへの唯一の参照であることがわからないからです。これが行われるメソッドは、言語とガベージコレクションシステムによって異なりますが、ActionScriptの基本的な取り決めは次のとおりです:今やFlashが現在多くのメモリを占有している場合は特に、ガベージコレクタは現在のSWF内のオブジェクトを検索し、参照を持たないすべてのオブジェクトを見つけます[4]。したがって、前の例では、文字列"blah"およびsomeStringを参照する唯一のものがsomeStringだった場合、"blah"はラベルに関連付けられていないため、Flashによって完全に到達できません。ガベージコレクタが次に実行されるときに、それを見つけて、そのメモリで完了したことをシステムに報告します。

ここで、特定の問題の具体的な詳細は、ソースを見なければ言い難いですが、問題の原因の1つにイベントリスナーがあることがわかります。場合によっては、関数を作成してイベントリスナーとして追加することがあります。今度はイベント自体はその関数[5]への参照を持っているので、関数がスコープから外れてもまだ参照があり、関数はガベージコレクタによって取得されません(関数はActionScript)。あなたはremoveEventListenerを呼び出すことによって手動でイベントハンドラを削除することができます(私はそれをお勧めしません)。またはaddEventListener()trueに呼び出してuseWeakReferenceパラメータを設定します。弱参照はガベージコレクタによって認識されないため、useWeakReferencetrueに設定すると、になるはずの状況がガベージコレクタによって検出されることはありませんが、誰かがイベントリスナーとして参照しているため。プロジェクト内のマウスイベントリスナーの数によって判断すると、これが原因かもしれません。 Flex Builderを使用している場合は、プロファイラを使用してメソッドのクロージャ数を確認できます。もし彼らが上ってきて、決して降りないなら、それはおそらくあなたの問題です。

[1]:これはvar exampleInt:int = 5;と書く場合のように、newキーワードを使用せずにオブジェクトを作成する場合にも当てはまります。
[2]:すべての単位が同じサイズであるため、私はuintを選択しました。それで4バイトとなることを自信を持って言い表すことができます。文字列は異なります。それらは含まれている文字の数に比例した量のメモリを占有するので、両方の例にStringを使用するのはもう少しあいまいです。
[3]:ActionScriptキーワードdeleteはこの目的のためのものではありません。このように使用しないでください。論理的には理にかなっており、非常に便利です。
[4]:Flashはmark-and-sweepスタイルの戦略を使用しますが、より具体的な詳細はhereとなります。 [5]:実際は、addEventListenerメソッドがclosuresを使用しているため太字になっていますが、私はそれを理解するのにはかなり弱いので、普通の人の英語にはできません。

0

これまで知らなかった理由を理解するのに役立つように、以前のバージョンのASでは、GCは表示リストに深く関連していました。シーンからオブジェクトを削除すると、それは(他の子オブジェクトと共に)存在しなくなり、それらへの参照はnullに変わりました。この動作は、既に知っているように、AS3ではかなり反対です。がんばろう!

関連する問題