1

単純なクラスで作業していて、オブジェクトの作成が重くないとします。

class Simple {
  public final int data1;
  public final float data2;
  ...
}

simple-objects を継続的にキューに入れる必要があります。

queue.add(new Simple(123,123f,...));

Object-Pool で作業し、Simple-Class の変更可能なクラスを変更する方が高速ですか? ないことを願っています。

4

2 に答える 2

6

一般的に、いいえ、速くはありません。「スループット」GC を使用するように JVM を構成すると、オブジェクトのリサイクルを試行しないため、パフォーマンスが向上します。「メモリに制約がある」場合、または GC の一時停止に問題がある場合にのみ、オブジェクト プールを検討する価値があります。(オブジェクトのガベージ コレクションの償却コストは、ガベージと非ガベージの割合が増加するにつれてゼロに近づく傾向があります。特に、世代仮説に従って、オブジェクトが「若くして死ぬ」場合)。

実際には:

  • アプリケーションがマルチスレッドの場合、オブジェクト プールが同時実行性のボトルネックになる可能性があります。

  • 「実質的に不変」なオブジェクトの変更には、追加のオーバーヘッドや追加の同期が必要になる場合があります。


オブジェクトの作成速度が「1 秒あたり約 20 オブジェクト」の場合、オブジェクト プールを使用してもパフォーマンスに大きな違いが生じる可能性は低いです。

計算する。

  • のオブジェクト サイズSimpleが N バイトで、1 秒あたり M を割り当てる場合、1 秒あたりに割り当てられるバイト数を見積もることができます。

  • 「若いスペース」が Y Mbytes の場合、その割り当て率に基づいて GC をトリガーするには T 秒かかります。

  • 「若いスペース」GC がサイズ Y のスペースに対して平均 G ミリ秒かかる場合、仮想的に節約できる時間の上限を見積もることができます... オブジェクト プールに関連するオーバーヘッドがゼロであると仮定します。

  • 「オーバーヘッドがゼロ」という仮定は非現実的であるため、実際の節約額はこれより少なくなります。

実際、「若い空間」の収集にかかる時間は、そのサイズだけに依存するわけではありません。また、保持する必要がある非ガベージの量にも依存します。(ガベージ以外の保持が少ないほど良い!) これにより、GC のオーバーヘッドを見積もるのが難しくなる可能性があります。ただし、オブジェクト プールを使用せずにアプリケーションを既にコーディングしている場合は、一般的なワークロードでのアプリケーションの「若い領域」の平均収集時間を測定し、それを上記の計算に組み込むことができます。

于 2015-08-19T15:00:31.913 に答える
1

実際に重いオブジェクトを作成している場合、またはオブジェクト プールの必要性を指定する他の要件がある場合、オブジェクト プールは理にかなっています。それ以外の場合は、新しいオブジェクトを作成し、JVM に依存して不要なものをすべて削除します (最初に不要なオブジェクトへの参照を削除/再割り当てすることを忘れないでください)。

于 2015-08-19T14:57:57.530 に答える