Java でのファイナライズ可能なオブジェクトに関する議論では、通常、ファイナライズ可能なオブジェクト (およびそれらに関連するリソース) を迅速にガベージ コレクションできない場合に発生する一般的な間接コストについて説明します。
現時点では、ファイナライズ可能であることの実際の直接コストが、メモリとオブジェクトの割り当て時間の両方でどのくらいかということにもっと興味があります。このようなコストの存在について、さまざまな場所で斜めに言及しているのを見てきました。たとえば、ファイナライズ メモリ保持の問題に関する Oracle の記事では、
が
obj
割り当てられると、JVMobj
はファイナライズ可能であることを内部的に記録します。これにより、通常、最新の JVM が持つ高速な割り当てパスが遅くなります。
JVM は、オブジェクト インスタンスがファイナライズ可能であることをどのように記録しますか? また、そのためにメモリとパフォーマンスのコストはどのくらいかかりますか?
私の特定のアプリケーションに興味がある人のために:
私たちは何百万もの信じられないほど軽量なオブジェクトを生成して保持しています。これらのオブジェクトに単一のポインターを追加するのは非常にコストがかかるため、フィールドのビットのサブセットにパックされた小さな数値 ID を使用する代わりに、オブジェクトからポインターを削除するためにかなりの作業を行いました。数値をアンパックすると、その ID を持つ共有の不変プロパティを、Map を使用してそれらを格納する Pool から取得できます。
残りの問題は、使用されなくなったプロパティ値のガベージ コレクションをどのように処理するかです。
検討されている戦略の 1 つは、参照カウントを使用することです。オブジェクトが作成され、プールされた値の ID を取得すると、その値の参照カウントがインクリメントされます。使用されなくなったら、デクリメントする必要があります。
このデクリメントを確実に行うためのオプションの 1 つは、次の finalize メソッドを追加することです。
public void finalize() {
Pool.release(getPropertyId());
}
ただし、ファイナライズ可能であるという行為そのものが、オブジェクトへの追加のポインターを保持する必要があることを意味する場合、このアプリケーションでは、ファイナライズ可能であるための初期コストが高くなると見なされます。追加のオブジェクトを割り当てる必要があることを意味する場合、ほぼ確実に高すぎます...したがって、私の質問:ファイナライズ可能にするための直接の先行コストはいくらですか?