2

クラスのライブラリを調べてウォークスルーするために、かなり重い反射を使用しています。静的フィールドとインスタンスの両方のフィールドを抽出して変更したいと思います。静的フィールドは簡単に見つけて変更できます。クラスを収集し、それらのフィールドのリストを要求し、フィールドを記録し、それらの値を検査/変更することができます。

インスタンスフィールドは異なります。Fieldオブジェクトへの参照を収集できますが、値を変更するには、そのタイプのオブジェクトをインスタンス化するコードを実行する必要があります。このコードが何をするのかわからないとしましょう。しかし、いくつかのオブジェクトをインスタンス化し、いくつかのコードを実行し、関心のあるライブラリを使用して処理を実行するメソッドblackBox()があります。実行後、クラス、C。

すべての静的フィールドのリストを収集し、それらの参照を十分に反復処理した場合、最終的にはコード内で存続しているすべてのインスタンスを見つけることができますか?つまり、私はそれを提案しています:

ガベージコレクションされていないJavaプログラムでインスタンス化されたすべてのオブジェクトには、静的フィールドで始まり、そのオブジェクトで終わる参照のチェーンが存在します。

これはJavaプログラムに関する一般的なルールですか?

編集:2つの追加の修飾子:

  1. スレッドを生成しないシーケンシャルプログラムにのみ興味があります。
  2. blackBox()の処理が終了し、ガベージコレクターが実行されたと想定しています。ライブラリ(moreBlackBox())を使用して、後で実行したいコードがさらにある可能性があります。アプリケーションが起動し、一時停止していると想像してください。
4

2 に答える 2

3

いいえ。静的フィールドから始まる参照のチェーンがあるか、または(おそらくより頻繁に)スレッドのスタック上のローカル変数から始まる参照のチェーンがあります。

public static void main(String[] args) {
    Foo foo = new Foo();
    doSomethingWithFoo(foo);
}

上記では、fooは実際には他のオブジェクト全体を再帰的に参照しますが、メインスレッドにはまだローカル変数fooがスタックにあるため、これらはすべてGCで収集できません。

于 2012-09-24T15:27:55.747 に答える
0

これは良い出発点かもしれません:

並行コレクターは、並行収集サイクル中にアプリケーションを2回一時停止します。最初の一時停止は、ルートから直接到達可能なオブジェクト(たとえば、スレッドスタック上のオブジェクト、静的オブジェクトなど)およびヒープ内の他の場所(たとえば、若い世代)をライブとしてマークすることです。この最初の一時停止は、初期マークと呼ばれます。2番目の一時停止は、マーキングフェーズの最後に発生し、アプリケーションスレッドの同時実行が原因で、同時マーキングフェーズ中に欠落したオブジェクトを検出します。2番目の一時停止はリマークと呼ばれます。

より深く読むために、考慮してください:

Oracleガベージコレクタのドキュメント

于 2012-09-24T15:34:29.193 に答える