答えて
64ビットJVM上で-XX:-UseTLAB -XX:NewSize=900m -mx1g
を使用して以下を実行する場合。
public static void main(String... args) throws NoSuchMethodException, IllegalAccessException {
for (int i = 0; i < 4; i++) {
long used1 = usedMemory();
populate(new HashMap());
long used2 = usedMemory();
populate(new ConcurrentHashMap());
long used3 = usedMemory();
System.out.println("The ratio of used memory is " + (double) (used3 - used2)/(used2 - used1));
System.out.println("For an extra " + ((used3 - used2) - (used2 - used1))/1000000 + " bytes per entry was used.");
}
}
private static void populate(Map map) {
for (Integer i = 0; i < 1000000; i++)
map.put(i, i);
}
private static long usedMemory() {
return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
}
あなたは100万エントリのJava 6と7を使用します。
The ratio of used memory is 1.1291128466982379
For an extra 8 bytes per entry was used.
The ratio of used memory is 1.1292086928728067
For an extra 8 bytes per entry was used.
The ratio of used memory is 1.1292086928728067
For an extra 8 bytes per entry was used.
The ratio of used memory is 1.1292086928728067
For an extra 8 bytes per entry was used.
メモリの8 MBは約5セントです。
私は実際に質問の前提を理解していません。あなたは同時性が必要なのか、そうでないのでしょうか。
しかし、this linkによると、空きのメモリフットプリントConcurrentHashMap
は1700バイトです。読み取り/書き込みアクセスが必要な複数のスレッドがある場合はConcurrentHashMap
を使用することをお勧めします。ただし、読み取りアクセスが必要なスレッドが多数ある場合はHashtable
が必要です。
ConcurrentHashMap
は、構成時および挿入時の両方で、HashMap
よりも大幅に多くのメモリを使用しません。使う初期
ConcurrentHashMap
で
は、HashMapのようなメモリのほぼ同じ量を使用して、余分な簿記の変数とロックのカップルのために少し以上であってもよいです。
初期化中、ConcurrentHashMap
は16個のセグメントを作成してキー値を格納します。各セグメントはHashMapに相当します。
各セグメントの初期容量/サイズは、初期容量全体の1/16です。したがって、本質的にConcurrentHashMap
は、1つのHashMapに相当する16の小さなHashMapsを作成します。各セグメントには独自のロックとブックキーピング変数(カウント、しきい値など)がありますが、これは余分なメモリオーバーヘッドです。
あなたはConcurrentHashMap
にのconcurrencyLevelパラメータに適切な値を渡すことでConcurrentHashMap
によって作成されたセグメントの数を制御することができます。この値が小さければ、使用されるスペースは少なくなりますが、スレッド数が多い場合は競合が増えます。この値が高いほど、セグメントが多く作成されますが、並列更新のパフォーマンスは向上します。注:concurrencyLevelパラメーターの値が大幅に高い場合は、スペースと時間の両方に影響します。
この小さなメモリオーバーヘッドは、開発者が並行処理と引き換えに受け入れるものです。挿入
で
セグメントをいっぱいにすると、そのセグメントのサイズが大きくなります。サイズを大きくするポリシーは、HashMapと同じです。 loadfactorパラメータは、セグメントのサイズを増やすタイミングを決定します。塗りつぶされたセグメントのみが増加することに注意してください。もう一度、メモリオーバーヘッドはHashMapとほとんど同じです。
全体としてConcurrentHashMap
は、HashMap
よりも大幅に多くのメモリを使用していませんが、ConcurrentHashMap
で使用されているすべての余分なバイトを測定することは本当に難しいです。
- 1. ConcurrentHashMapコンストラクタのパラメータ?
- 2. ConcurrentHashMapのロック
- 3. Java ConcurrentHashMapのパターン
- 4. フィルタConcurrentHashMap値で
- 5. ConcurrentHashMapのlock()メソッド
- 6. ConcurrentHashMap修飾子の同期
- 7. Android 2.1 SDK + ConcurrentHashMap $ ValueIteratorとGC
- 8. boost :: property_tree :: ptreeのメモリオーバーヘッドは何ですか?
- 9. C++:仮想化によるメモリオーバーヘッド?
- 10. Java ConcurrentHashMapアトミック・ゲット(存在する場合)
- 11. ConcurrentHashMapのビットワイズシフト演算子の使用
- 12. memcachedに(1ビット)オブジェクトを格納するメモリオーバーヘッドは何ですか?
- 13. Lucene Sortはメモリオーバーヘッドを増加させます
- 14. HaskellのConcurrentHashMapの類推は何ですか?
- 15. Java ConcurrentHashMapから特定の項目を削除します
- 16. ConcurrentHashMap $ HashEntryの "next"フィールドが最終的な理由
- 17. 静的ConcurrentHashmapで外部同期が必要です
- 18. "CopyOnWriteArrayList"と "ConcurrentHashMap"をシリアル化できますか?
- 19. Java Concurrency:HashMapとConcurrentHashMapのget(Key)はパフォーマンスが同じですか?
- 20. なぜNettyには独自のConcurrentHashMapがありますか?
- 21. ConcurrentHashMapがあるので、Hashtableが必要ですか?
- 22. 共有ASP.NETアプリケーションを使用したIISセットアップでのメモリオーバーヘッドの削減
- 23. ConcurrentHashMapがスレッドセーフであることをどのようにテストできますか?
- 24. ConcurrentHashMapはServlet内で使用する信頼できる選択肢ですか?
- 25. HashtableのすべてをConcurrentHashmapに置き換えても安全ですか?
- 26. JavaでConcurrentHashMapを再ハッシュするとセグメント数が増えますか?
- 27. Java 7 HashMapの単一のエントリ(キーと値のペア)のメモリオーバーヘッドは何ですか? (64ビットOracle Hotspot JVMを使用)
- 28. Jqueryコールバックとして使用すると、匿名関数と名前付き関数のメモリオーバーヘッド
- 29. C#:どのメモリオーバーヘッドを使用しますか?文字列または単語のシーケンスを保持するchar?
- 30. ヒープメモリ割り当てに関連するメモリオーバーヘッド(ヒープ内のマーカーなど)はありますか?
ConcurrentHashMapを多数作成するのは意味がありません。コア数が限られているだけです。少数のCHMのオーバーヘッドは1セント未満のメモリになる可能性があります。 –
@PeterLawrey私は本当にあなたのポイントを取得していません。 「大量のConcurrentHashMapを作成するのは無駄です。彼らはまだオーバーヘッドを持っています。さらに、同時に多くのCHMを持つことは明らかに奇妙であっても、短命オブジェクトが構築時に同時にハッシュマップを作成することを容易に想像することができます(DB指向のソフトウェアの結合演算子を考えてみましょう)。 – Maxime
同時収集を使用する理由は、収集数よりもコア数が多いためです。コアよりもコレクションの数が多い場合は、同時にアクセスする可能性はほとんどありません。 –