11

「新品」はどれくらい高いですか?つまり、同じオブジェクトを再利用することを目指すべきですか、それともオブジェクトが「範囲外」である場合、それを空にすることと同じですか?

たとえば、メソッドがリストを作成するとします。

List<Integer> list = new ArrayList<Integer>(); 

メソッドの最後で、リストは使用されなくなります。これは、リストにメモリが割り当てられていないことを意味しますか、それとも(「作成された」ために)リストへのnullポインタがあることを意味します。

または、「リスト」をメソッドに送信し、メソッドの最後で次のように空にするlist.removeAll(list);こともできます。これにより、メモリの観点から何か違いが生じますか?

ありがとう!

4

6 に答える 6

15

配列リストなので、新しいオブジェクトを作成するということは、メモリのスラブを割り当ててゼロにすることと、簿記のオーバーヘッドを意味します。リストをクリアすることは、メモリをゼロにすることを意味します。このビューは、既存のオブジェクトをクリアする方が速いと信じさせるでしょう。ただし、JVMはメモリ割り当てを高速化するように最適化されている可能性が高いため、おそらくこれは問題になりません。したがって、明確で読みやすいコードを書くだけで、心配する必要はありません。これは結局のところjavaであり、cではありません。

于 2012-02-16T15:47:27.050 に答える
4

メソッドの最後で、リストは使用されなくなります。これは、リストにメモリが割り当てられていないことを意味しますか、それとも(「作成された」ために)リストへのnullポインタがあることを意味します。

それへの参照がなく、オブジェクトがGCに適格であることを意味します。

または、「リスト」をメソッドに送信し、メソッドの最後で次のように空にすることもできます。list.removeAll(list); それは記憶の観点から何か違いを生むでしょうか?

それは時間/空間間のトレードオフです。新しいオブジェクトを作成する必要はありませんが、リストから要素を削除するには時間がかかります。

最新のJVMGC収集機能を使用すると、必要に応じて新しいオブジェクトを作成できます(ただし、ループ内でのオブジェクトの作成は避けるのが最善です)。オブジェクトへの参照が長くなると、そのオブジェクトがGCの対象外になることがあり、適切に処理されないとメモリリークが発生する可能性があります。

于 2012-02-16T15:41:10.440 に答える
2

Javaのメモリフットプリントについてはよくわかりませんが、リストを空にして再利用することは、リストを空にすることによるパフォーマンスへの影響があるため、あまり良い考えではないと思います。そして、それはOOの観点からも良い考えではないと思います。なぜなら、1つの目的だけで1つのオブジェクトを持つ必要があるからです。

メソッドの最後では、オブジェクトは実際にスコープ外です。ただし、他の人がそのリストを参照している可能性があるため、ガベージコレクションされている、またはガベージコレクションの対象であるという意味ではありません。つまり、基本的に、そのリストへのオブジェクト参照がない場合は、ガベージコレクションの対象となる可能性がありますが、ガベージコレクションが行われる場合は、まだ不明です。リストがまだ若い世代のスペースに保存されている場合は、エデンにある可能性があります。スペースまたはテニュアスペース。エデンスペースは、オブジェクトが最初に割り当てられる場所です。ガベージコレクションが発生し、オブジェクトがまだ生きている場合、オブジェクトはサバイバースペースに移動されます。それがそれを過ぎても生き残った場合、それはテニュアスペースに移動します。そこでは、ガベージコレクションはあまり発生しないと思います。しかし、これはすべて、オブジェクトの存続期間、このオブジェクトを参照するユーザー、およびオブジェクトが割り当てられる場所によって異なります。

于 2012-02-16T15:44:51.913 に答える
2

「新品」はどれくらい高いですか?

それは確かにいくらかのオーバーヘッドを招きます。ただし、オブジェクトの複雑さによって異なります。プリミティブが少ないオブジェクトを作成する場合は、それほど高価ではありません。ただし、オブジェクト内にオブジェクトを作成している場合は、オブジェクトのコレクションである可能性があります。コンストラクターがオブジェクトのメンバー変数を初期化するためにいくつかのプロパティファイルを読み取っている場合は、費用がかかります。

しかし、率直に言って、新しいオブジェクトを作成する必要がある場合は、それ作成しました。代替手段はありません。そして、私たちがそうする必要がなく、私たちがまだ作成しているのであれば、それは一種の悪いプログラミングです。

メソッドの最後で、リストは使用されなくなります。これは、リストにメモリが割り当てられていないことを意味しますか、それとも(「作成された」ために)リストへのnullポインタがあることを意味します。

オブジェクトへの参照がなくなると、オブジェクトはスコープ外になり、ガベージコレクションの対象になります。したがって、メモリが割り当てられている場合でも、後でGCによって再利用されます。実行するたびに、心配する必要はありません。(そして、GCがいつ実行されるかを保証することはできません)。

最後にコレクションを空にしても、コレクション自体に起こることと同じことがコレクション内のすべての個々のオブジェクトに起こるため、これ以上改善されるとは思いません。彼らはGCの対象となります。

于 2012-02-16T15:48:39.287 に答える
2

小さなリストの場合、リストよりも少し安いでしょうclear()

非常に大きなヒープ内の非常に大きなリストの漸近的なケースの場合、GCがforループインよりも速くメモリの大きなチャンクをゼロにできるかどうかに要約されclear()ます。そして、私はそれがおそらくできると思います。

ただし、オブジェクトの回転率が高いという説得力のある証拠(プロファイリングから)がない限り、これを無視することをお勧めしArrayListます。(直感だけに基づいて最適化することはお勧めできません。)

于 2012-02-16T16:02:04.890 に答える
2

これは、必要な初期化とメモリフットプリントの大きさの両方の観点から、オブジェクトのコストに依存します。また、アプリケーションの種類(アプリケーションが他に何に時間を費やすか)にも大きく依存します。

ArrayListを使用した例では、明確な答えを出すのはすでに非常に困難です。リストにあるエントリの数に応じて、clear()は非常に高価または非常に安価になる可能性がありますが、新しいArrayListのコストはほぼ一定です。

一般的な経験則は次のとおりです。パフォーマンスの問題があることを測定するまでは、オブジェクトの再利用を気にしないでください。その後、オブジェクトの作成がその問題の原因であることを確認してください。ほとんどの場合、アプリケーションにはもっとやりがいのある最適化の機会があります。プロファイラーは、最も時間を費やしている場所を特定するのに役立ちます。それらとより良いalgoryhtmsに焦点を合わせます。

于 2012-02-16T17:10:10.720 に答える