如何填满一个HashMap?
Posted vs2015
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何填满一个HashMap?相关的知识,希望对你有一定的参考价值。
如何填满一个HashMap?
step_1 : 计算所需内存
在64位JVM情况下,对象markword占8个字节,指向类的指针占8个字节。
|------------------------------------------------------------------------------|--------------------|
| Mark Word (64 bits) | State |
|------------------------------------------------------------------------------|--------------------|
| unused:25 | identity_hashcode:31 | unused:1 | age:4 | biased_lock:1 | lock:2 | Normal |
|------------------------------------------------------------------------------|--------------------|
| thread:54 | epoch:2 | unused:1 | age:4 | biased_lock:1 | lock:2 | Biased |
|------------------------------------------------------------------------------|--------------------|
| ptr_to_lock_record:62 | lock:2 | Lightweight Locked |
|------------------------------------------------------------------------------|--------------------|
| ptr_to_heavyweight_monitor:62 | lock:2 | Heavyweight Locked |
|------------------------------------------------------------------------------|--------------------|
| | lock:2 | Marked for GC |
|------------------------------------------------------------------------------|--------------------|
HashMap的每一个节点结构如下:
static class Node<K,V> implements Map.Entry<K,V> {
final int hash; //4个字节
final K key; //8个字节
V value; //8个字节
Node<K,V> next; //8个字节
//以下省略
}
综上所述,每一个Node
在默认8字节对齐后占48字节。
HashMap规定最多含有2G个Node
2G*48=96G
/**
* The maximum capacity, used if a higher value is implicitly specified
* by either of the constructors with arguments.
* MUST be a power of two <= 1<<30.
*/
static final int MAXIMUM_CAPACITY = 1 << 30;
若K 为Integer类型,则K 内存占24字节
2G*24=48G
HashMap 中 table
字段如下
/**
* The table, initialized on first use, and resized as
* necessary. When allocated, length is always a power of two.
* (We also tolerate length zero in some operations to allow
* bootstrapping mechanics that are currently not needed.)
*/
transient Node<K,V>[] table;
按照该数组的最大长度(2^31)约等于2G
注:实际上在Hotspot下数组的最大索引为2^31-3
2G*8=16G
综上:填满一个HashMap 至少需要96G+48G+16G=160G
内存
step_2 : 测试代码
import java.util.HashMap;
public class TestMaxHashMap {
public static void main(String[] args) {
Integer a= 0;
System.out.println("process:"+Runtime.getRuntime().availableProcessors());
System.out.println(Runtime.getRuntime().maxMemory()/(1024*1024*1024)+"G");
long begin=System.currentTimeMillis();
System.out.println("begin at :"+begin);
HashMap<Integer,Integer> hashMap=new HashMap<>(Integer.MAX_VALUE);
for (int i = 0; i < Integer.MAX_VALUE; i++) {
hashMap.put(i,a);
}
System.out.println("current size: "+hashMap.size());
long end=System.currentTimeMillis();
System.out.println("end at :"+end);
long expire=end-begin;
System.out.println("expire "+expire+" mill");
System.out.println("maxMemory : "+Runtime.getRuntime().maxMemory());
System.out.println("freeMemory : "+Runtime.getRuntime().freeMemory());
System.out.println("totalMemory : "+Runtime.getRuntime().totalMemory());
System.out.println("I will add first ");
hashMap.put(-10086,a);
System.out.println("currentSize: "+hashMap.size());
System.out.println("I will add second ");
hashMap.put(-10087,a);
System.out.println("currentSize: "+hashMap.size());
System.out.println("I will add third ");
hashMap.put(-10088,a);
System.out.println("currentSize: "+hashMap.size());
System.out.println("the project end !");
}
}
step_3 : 硬件配置
主机为32核256G云服务器
内存:
ubuntu@VM-0-10-ubuntu:~$ free
total used free shared buff/cache available
Mem: 264023320 210517376 52956076 8848 549868 52200720
Swap: 0 0 0
CPU:
ubuntu@VM-0-10-ubuntu:~$ lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 32
On-line CPU(s) list: 0-31
Thread(s) per core: 1
Core(s) per socket: 32
Socket(s): 1
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 94
Model name: Intel(R) Xeon(R) Gold 6133 CPU @ 2.50GHz
step_4 : 运行结果
运行结果如下
ubuntu@VM-0-10-ubuntu:~$ java -Xms250g TestMaxHashMap
process:32
239G
begin at :1587032320457
current size: 2147483647
end at :1587033300316
expire 979859 mill
maxMemory : 257250820096
freeMemory : 93706040008
totalMemory : 257250820096
I will add first
currentSize: -2147483648
I will add second
currentSize: -2147483647
I will add third
currentSize: -2147483646
the project end !
填满大概需要15min
可以看出当超出Integer.MAX_VALUE
时 HashMap 并不会抛异常
以上是关于如何填满一个HashMap?的主要内容,如果未能解决你的问题,请参考以下文章