4

ガベージ コレクションが必要な新しいオブジェクトを作成せずに、Java で HashMap の値を繰り返し処理しようとしています。次のように、強化された for ループを使用して、値を反復処理するのは簡単です。

for (Value v : myMap.values()) {
    ....
}

しかし、これは舞台裏で Iterator オブジェクトを作成します (私は思いますか?)

私が思いついた最高のものは、このコードです:

Object[] values = myMap.values.toArray();
...standard "int i" for loop on the array

しかし、正直に言うと、GC がこの配列で何をするかはわかりません。

これを行う完璧な方法はありますか、または 1 つの再利用可能なオブジェクトでこれを行う方法はありますか?

編集: これは Android ゲーム用であり、オブジェクトを作成してパフォーマンスに影響を与えるようなループがたくさんあります。

編集 #2: 疑っている方のために説明すると、最も一般的に呼ばれる強化された for ループの一部 (主に ArrayLists) のリファクタリングは、jvisualvm ヒープ プロファイリングに基づくメモリ使用量に大きな影響を与えました。もちろん、これの一部はおそらく、ArrayList が多すぎるか、実際には必要ないときにそれらをループするためです。

4

2 に答える 2

3

しかし、これは舞台裏で Iterator オブジェクトを作成します (私は思いますか?)

はい、そうなります。

私が思いついた最高のものは、このコードです:

  Object[] values = myMap.values.toArray();
  ...standard "int i" for loop on the array

しかし、正直に言うと、GC がこの配列で何をするかはわかりません。

Iterator実際、これは明示的または暗黙的にを使用するよりも悪くなります。

  • このtoArray()メソッドは、新しい配列を割り当て、値セットの要素をそこにコピーします。
  • への呼び出しは、オブジェクトをインスタンス化するvalues() 場合がありSetます。
  • への呼び出しは、新しいインスタンスを作成する値セット オブジェクトをtoArray()内部的に呼び出します。iterator()Iterator

したがって、Iteratorとにかく、AND 一時配列、および (おそらく)Setオブジェクトを割り当てています。


ヒープのプロファイリングを行ったところ、最大のオブジェクト セットがありましたArrayList$Itr(このHashMap例とは関係ありませんが、現在、強化されたすべての for ループを標準の for ループに書き直しています)。

ご指摘のとおり、それは別のケースです。しかし、私はまだあなたがここで間違った木を吠えていると思います. 最近の HotSpot JVM を使用している場合、有効期間が短いオブジェクト (つまり、Tenured されないオブジェクト) の割り当てとガベージ コレクションのコストは非常に小さくなります。オブジェクトの割り当て率を下げる特別な理由がない限り、実際に測定可能なパフォーマンスの向上という点で、すべての作業がほとんど達成されない可能性があります。

于 2013-08-21T08:55:59.720 に答える