6

こんにちは、私のプログラムが通常、私が望むよりも遅く実行される理由を発見しようとしています。


たとえば、いくつかの洞察が必要なコードがあります

1. while(conditionIsTrue){
2.      Object object = new Object();
3.  }

2行目。新しいオブジェクトを作成します。これは、私のプログラムで何千回も発生します。nullgc が破棄する前に、特に古いオブジェクトを削除する必要がありますか? または、gc は私のプログラムの後ろに移動し、他のオブジェクトが使用したすべてのメモリを取得します。

または、別のオプションとして、これが発生しています。一定量のメモリが割り当てられており、新しいオブジェクトを作成するたびに、まったく同じメモリに割り当てられます。


Bruno は、実行速度が遅い理由を理解できるように、より現実的なコードを見せてほしいと私に依頼しました。しかし、あなたの答えのおかげで、ブルーノは私がこのようなコードを持っていることに気付きました

1. Object object = null;
2. while(conditionIsTrue){
3.      object = new Object();
4.  }

それで、オブジェクトへの強力な参照があることに気付きました。ありがとうブルーノ!

4

2 に答える 2

18

この場合、object = null;GC が をクリアできるようにする必要はありません。これnew Object()は、オブジェクトをインスタンス化した反復が終了した直後 (つまり、3 行目) にオブジェクトへの参照が残っていないためです。

ルールは次のとおりです。GC は、それを指している強い参照がなくなるたびにオブジェクトをクリアできます。オブジェクトはすぐにクリアされないかもしれませんし、時間がかかるかもしれませんが、オブジェクトへの新しい強力な参照を取得できない限り (そうです、方法はあります!SoftReferenceWeakReferenceを参照してください)、最終的にはクリアされ、確実にスローされる前にクリアされます。 OutOfMemoryError。_

また、JVM はメモリの割り当てに関して非常にスマートです。エスケープ解析と呼ばれるものがあります。これにより、JVM は がそのループの外では使用されていないことを理解できるため、ヒープではなくスタックnew Object()でオブジェクトにメモリを割り当てることさえできます! したがって、その特定のオブジェクトには GC がまったく必要ない場合があります。メソッドが終了すると、オブジェクトは自動的にクリアされます。

JVM は、そのオブジェクトをインスタンス化してもまったく目立った効果がないことを検出し、単純にその行 #2 を実行しないことを選択した可能性さえあると推測します (ただし、これは推測であり、最適化は、コンパイラを書いていました -- これが起こるか起こらないかを誰かが確実に知っているなら、コメントを追加してください!)。

プログラムの実行速度が思ったよりも遅い場合は、より現実的なコードを表示する必要があります。実際のコードとあなたが尋ねたスニペットとの微妙な違いと考えられるものは、JVM にとっては大きな違いかもしれません!

于 2013-06-25T00:58:49.280 に答える