問題は、Object2のインスタンスが、各ループ反復の終了時にガベージコレクションを取得していないことです...。これは予想されることですか?
はい、そうです。JVMのデフォルトの動作は、最も効率的なときにガベージコレクターを実行することです。これは通常、「新しい」スペースがいっぱいになることを意味します。GCは確かに「熱心」ではなく、オブジェクトが到達不能になるとすぐにオブジェクトを再利用しようとはしません。
Object2インスタンスのクリーンアップを強制して、各ループが新たに開始されるようにする方法はありますか?
System.gc()
ガベージコレクターを今すぐ実行するためのヒントとして呼び出すことができます。ただし、JVMはヒントを無視するように構成できます。
これは悪いプログラム設計ですか?
通常、を呼び出すのは悪い設計System.gc()
です。GCの実行は比較的費用がかかり、(人間工学的な観点から)必要のないときに頻繁に実行することは非常に無駄です。
すぐに実行されるGCに依存するコードを書くことは常に悪い設計です。確かに、習慣の使用を必要とするものはすべて、finalize()
大きな疑いを持って扱われるべきです。
私はあなたの本当の問題はこれだと思います:
....したがって、Object2の静的instancecount変数は、反復ごとに(メモリ使用量とともに)大きくなります。
これはある意味で真実です。しかし、最終的には、JVMはGCを実行するのに適した時期であると判断し、すべてのオブジェクトが再利用されます。これがGCの仕組みです。
あなたの本当の問題は(私が思うに)まだ回収されていないすべてのガベージオブジェクトを保持するためにかなりの量のメモリが必要であるという事実に不快感を覚えていることです。しかし、その反面、GC ...とアプリケーション...は、十分なメモリを使用できる場合、より高速に実行されます。驚いたことに、割り当てと再利用の両方が、GCが(たとえば)参照カウントを使用してオブジェクトができるだけ早く再利用されるようにする場合よりもはるかに高速です。
もう1つ注意すべき点は、インスタンスカウンターをデクリメントするには、ファイナライザーを使用する必要があるということです。これには、GCのオーバーヘッドが大幅に増加し、オブジェクトの最終的なリサイクルが遅くなるという不幸な副作用があります。
(メインGCは、オブジェクトがファイナライズ可能であることを認識し、後でファイナライズするためにキューに追加します。ファイナライズ可能なオブジェクトと到達可能なオブジェクトは、すぐに再利用できるオブジェクトのリストから削除されます。後でポイント、ファイナライズスレッドはキューを反復処理し、finalize
各メソッドのメソッドを呼び出します。これによりオブジェクトが完全に到達不能になった場合、次のGC実行でオブジェクトが再利用されます。)