1

JVM でのメモリ管理について読んでいますが、オブジェクトへの参照がなくなった場合、ガベージ コレクションが行われます。たとえば、私はプログラムを持っています

public test {
  public static void main(String[ ] args) {
      String name = "hello";  
      for (int i =0 ; i < 5; i++) {
         System.out.println(i);
       }
   }
}

ご覧のとおり、String nameはどこにも使用されていないため、その参照は最後まで保持され、ガベージ コレクションは行われません。

今私が持っています、

String name = "hello"
  String name2 = name.substring(1,4)//"ell"

ここでも、 の参照はhello常に存在している必要があり、ガベージ コレクションを使用することはできませんname2

では、参照はあるが廃止された、つまりコードで使用されなくなったこれらStringまたはいずれかがガベージコレクションされるのはいつですか?objects

配列を縮小するとメモリ リークが発生するシナリオが 1 つあります。したがって、配列の参照を null に設定することは、これらの古い参照をガベージ コレクションする良い方法です。

4

3 に答える 3

1

技術的には、JVM はオブジェクトをガベージ コレクションする必要はありませ。実際には、通常、最後の参照がなくなってから少し遅れてメモリを解放します。

まず、定数は常に存在することに注意してください。に新しい値を割り当てても、システムには、その初期化ステートメントをヒットするたびに再利用されるクラスと共に保存されnameた のコピーがまだあります。"hello"

ただし、ある種の計算にオブジェクトを使用することと、オブジェクトへの参照を永久に保持することを混同しないでください。2番目の例では、 while"hello"は実際には維持されていますが、それは定数プールに住んでいるからです。name2それをメモリに保持するような「ホールド」はありません。への呼び出しがsubstring実行されて終了し、永遠に続くことはありませんname。(Oracle JVM での実際の実装は、基礎となる を共有しますchar[]が、それは実装に依存します。)

配列は長寿命で再利用されることが一般的であるため、配列を消去することをお勧めします。配列全体がガベージ コレクションされると、それが保持する参照が消去されます (それらが最後のものである場合は、それらのオブジェクトのガベージ コレクションが行われます)。

于 2013-09-05T23:43:21.837 に答える
1

配列を縮小するとメモリ リークが発生するシナリオが 1 つあります。したがって、配列の参照を null に設定することは、これらの古い参照をガベージ コレクションする良い方法です。

文字列は参照型であるため、ガベージ コレクションに関する参照型の規則はすべて文字列に適用されます。JVM は文字列リテラルに対してもいくつかの最適化を行う場合がありますが、これらについて心配している場合は、おそらく考えすぎです。

JVM が参照されていないオブジェクトを収集するのはいつですか?

重要な唯一の答えは次のとおりです。それはわかりませんし、その必要もありません。確定的ガベージ コレクションに関連する Java コードを記述しないでください。それは不必要であり、醜さをはらんでいます。

一般的に言えば、参照変数 (参照型の配列またはコレクションを含む) を可能な限り狭い範囲に限定すれば、メモリ リークを心配する必要がなくなります。寿命の長い参照型には、ある程度のケアとフィードが必要です。

配列の「トリミング」(割り当てによる配列要素の参照解除null) は、配列がメモリを管理するための独自のシステムを表す特別な場合にのみ必要です。オブジェクトの独自のキャッシュまたはキューを作成している場合。

JVM は配列が「メモリを管理している」ことを認識できないため、まだ参照されているが有効期限が切れている未使用のオブジェクトを収集することはできません。配列がメモリを管理するための独自のシステムを表す場合、nullオブジェクトが期限切れになっている配列要素に割り当てる必要があります (たとえば、キュ​​ーからポップされました。J. Bloch、Essential Java、第 2 版)。

于 2013-09-06T00:31:20.870 に答える