12

割り当てられたすべてのオブジェクトを追跡し、それらへの使用可能な参照がなくなるとすぐにそれらの割り当てを解除するガベージ コレクターがある場合でも、メモリ リークが発生する可能性はありますか?

メモリリークが参照なしの割り当てであると考えると、それは不可能ではないか、何か不足していますか?

編集:だから私がメモリリークとして数えているのは、コードで参照されなくなった割り当てです。まだ参照している大量の累積割り当ては、ここで検討しているリークではありません。

また、通常の最先端の GC について話しているだけです。しばらく経ちましたが、循環参照のようなケースではつまずかないことがわかっています。どの言語についても具体的な回答は必要ありません。これは、友人との会話から得たものです。Actionscript と Java について話していましたが、それらに固有の回答は気にしません。

Edit2:その音から、コードが割り当てを参照する機能を完全に失い、GC がそれを取得できない可能性がある理由はないようですが、私はまだ検討するのを待っています.

4

4 に答える 4

17

あなたの質問が本当にこれなら:

メモリリークが参照なしの割り当てであると考えると、それは不可能ではないか、何か不足していますか?

その場合、答えは「はい、それは不可能です」です。適切に実装されたガベージ コレクターは、アクティブな参照を持たないすべての割り当てを再利用するためです。

ただし、(たとえば) Java では確実に「メモリ リーク」が発生する可能性があります。私の「メモリ リーク」の定義は、まだアクティブな参照がある (ガベージ コレクターによって再利用されないようにする) 割り当てです、プログラマーはオブジェクトが再利用可能でないことを知りません (つまり、プログラマー、このオブジェクトは無効であり、再利用する必要があります)。簡単な例は次のようなものです。

オブジェクト A -> オブジェクト B

この例では、ObjectA はコード内でアクティブに使用されているオブジェクトです。ただし、ObjectA には事実上無効な ObjectB への参照が含まれています (つまり、ObjectB は割り当てられて使用され、プログラマーの観点からは無効になっています) が、プログラマーは ObjectA の参照を null に設定するのを忘れていました。この場合、ObjectB は「リーク」されています。

大きな問題には思えませんが、これらのリークが累積する状況があります。ObjectA と ObjectB が実際には同じクラスのインスタンスであるとします。そして、そのようなインスタンスが使用されるたびに、プログラマーが null への参照を設定するのを忘れるというこの問題が発生します。最終的には次のようになります。

ObjectA -> ObjectB -> ObjectC -> ObjectD -> ObjectE -> ObjectF -> ObjectG -> ObjectH -> など...

現在、ObjectB から ObjectH までがすべてリークされています。そして、このような問題は (最終的には) プログラムをクラッシュさせます。ガベージコレクタが適切に実装されていても。

于 2012-05-16T13:18:44.473 に答える
2

プログラムにメモリ リークがあるかどうかを判断するには、まずリークとは何かを定義する必要があります。S次のような状態と一連の入力が存在する場合、プログラムにメモリリークがあると定義しますI

  1. プログラムが状態 `S` にあり、入力 `I` を受け取った場合、プログラムはまだ状態 `S` のままですが (クラッシュしない場合)、しかし...
  2. 上記のシーケンスを「N」回繰り返すために必要なメモリの量は際限なく増加します。

ガベージ コレクションされたフレームワーク内で完全に実行されるプログラムでは、上記で定義したメモリ リークが発生する可能性があります。これが発生する一般的な方法は、イベント サブスクリプションです。

スレッド セーフなコレクションがCollectionModifiedイベントを公開しIEnumerator<T>、そのメソッドによって返されたIEnumerable<T>.GetEnumerator()が作成時にそのイベントにサブスクライブし、 でサブスクライブを解除するとしDisposeます。このイベントは、コレクションが変更された場合でも列挙を適切に進めるために使用されます (たとえば、オブジェクトが列挙全体を通じて連続してコレクション内にあることを保証することは、1 回だけ返されます。その一部の間に存在するオブジェクトは 1 回しか返されません)。 . ここで、そのコレクション クラスの有効期間が長いインスタンスが作成され、特定の入力によって列挙されるとします。CollectionModifiedイベントが、破棄されていないすべての への強い参照を保持している場合IEnumerator<T>、コレクションを繰り返し列挙すると、無制限の数の列挙子オブジェクトが作成され、サブスクライブされます。メモリーリーク。

于 2012-05-17T00:02:26.003 に答える
0

メモリ リークは、ガベージ コレクション アルゴリズムがどれほど効率的であるかに依存するだけではありません。たとえば、インスタンス変数や静的変数で、使用されずに寿命の長いオブジェクト参照をプログラムが保持している場合、プログラムでメモリ リークが発生します。

参照カウントには循環参照の既知の問題があります。

Object 1 refers to Object 2 and Object 2 refers to Object 1 

しかし、誰もオブジェクト 1 またはオブジェクト 2 を参照していないため、このシナリオでは参照カウント アルゴリズムが失敗します。

ガベージ コレクター自体に取り組んでいるので、さまざまな実装戦略について読む価値があります。

于 2012-05-14T04:42:14.120 に答える
0

別の方法で GC でメモリ リークが発生する可能性があります。単純にメモリをスキャンし、ポインタのように見えるすべてのものについて、「指す」メモリを解放しない保守的なガベージ コレクタを使用すると、到達不能なメモリが残る可能性があります。割り当てられます。

于 2012-05-17T15:16:57.607 に答える