答えて
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. neo4jのメモリオーバーヘッド
- 2. int tbbメモリオーバーヘッド
- 3. ConcurrentHashMapのロック
- 4. フィルタConcurrentHashMap値で
- 5. ConcurrentHashMapコンストラクタのパラメータ?
- 6. ConcurrentHashMapのconcurrencyLevel
- 7. ConcurrentHashMapのlock()メソッド
- 8. Java ConcurrentHashMapアクションアトミック性
- 9. Java ConcurrentHashMapのパターン
- 10. HashMap to concurrentHashMap
- 11. なぜConcurrentHashMap :: putIfAbsentがConcurrentHashMap :: computeIfAbsentより速いのですか?
- 12. python multiprocessing.Array:巨大な一時メモリオーバーヘッド
- 13. C++:仮想化によるメモリオーバーヘッド?
- 14. boost :: property_tree :: ptreeのメモリオーバーヘッドは何ですか?
- 15. ConcurrentHashMap修飾子の同期
- 16. Android 2.1 SDK + ConcurrentHashMap $ ValueIteratorとGC
- 17. ConcurrentHashMapでの同時修正
- 18. Java 8 ConcurrentHashMapの初期化
- 19. Java ConcurrentHashMapアトミック・ゲット(存在する場合)
- 20. 同期メソッドConcurrentHashMapの同時実行レベル
- 21. シナリオ:ConcurrentHashMapを使用する理由
- 22. ConcurrentHashMapの要素の増分と削除
- 23. タブレットとNexsusでのConcurrentHashMapの差分パフォーマンス
- 24. は、この記事でのConcurrentHashMap
- 25. ConcurrentHashMapのビットワイズシフト演算子の使用
- 26. scala TrieMapとJava ConcurrentHashMapの相違点
- 27. リストにオブジェクトを直接追加するときのメモリオーバーヘッド
- 28. メモリオーバーヘッドなしでEigen :: SparseMatrixのスパースパターンを設定する
- 29. Lucene Sortはメモリオーバーヘッドを増加させます
- 30. memcachedに(1ビット)オブジェクトを格納するメモリオーバーヘッドは何ですか?
ConcurrentHashMapを多数作成するのは意味がありません。コア数が限られているだけです。少数のCHMのオーバーヘッドは1セント未満のメモリになる可能性があります。 –
@PeterLawrey私は本当にあなたのポイントを取得していません。 「大量のConcurrentHashMapを作成するのは無駄です。彼らはまだオーバーヘッドを持っています。さらに、同時に多くのCHMを持つことは明らかに奇妙であっても、短命オブジェクトが構築時に同時にハッシュマップを作成することを容易に想像することができます(DB指向のソフトウェアの結合演算子を考えてみましょう)。 – Maxime
同時収集を使用する理由は、収集数よりもコア数が多いためです。コアよりもコレクションの数が多い場合は、同時にアクセスする可能性はほとんどありません。 –