一个1000万HashMap,会占用多少空间内存?

本文详细分析了包含1000万条数据的HashMap在内存中的占用情况,采用特定假设条件,计算出该HashMap大约占用1208MB的内存空间。

问题

一个1000万HashMap,会占用多少空间内存?其中,Key=String(长度不超过16字符,且重复性极小),Value=Integer


HashMap内存主要组成部分

  1. table 数组所占内存

  2. table 中的每个元素 Entry 所占内存

假设

为了方便统计,我们做如下假设:

  1. Key hash 之后的结果完全不重复(单个 bucket 最多一条记录)。

  2. loadFactor = 0.75 (默认值)。

  3. JDK 版本:
    jvm

    64位JVM,本来reference应该是8byte,但是对象指针压缩XX:+UseCompressedOops默认就是开启的,reference变为4byte。

Java对象内存布局

对象头(header) + 实例数据 + padding(align)

对象头大小:16byte,默认开启对象指针压缩之后,变为为12byte。
padding(align):8byte对齐。

table数组所占空间

存放1千万记录,经过多次 resize 之后:table.length() = 16777216

table 数组所占用空间为 = 16777216 * 4(数组的每一项都是一个Entry引用) + 16 (java arrays header size) = 67108864 + 16 = 67108880

Entry空间统计

entry

不考虑reference,单个Entry对象所占空间为:32

reorder 之后的顺序如下:
object header size = 12
int hash =  4
reference key = 4
reference value =  4
reference next =  4
padding(align)= 4

然后 key 所占空间:72

String 
object header size = 12
int hash = 4
int hash32 = 4
reference value[] = 4char[]
arrays header size = 16
char[] = 16 * 2 (一个字符两个字节  utf - 16)

value 所占空间:16

Integer 
object header size = 12 
int value = 4

1千万记录对应1千万个 Entry 对象,占用总空间为: 10000000 * (32 + 72 + 16) = 1200000000

总的空间

67108880 + 1200000000 = 1267108880 / 1024 * 1024 = 1208M

参考

http://www.codeinstructions.com/2008/12/java-objects-memory-structure.html
http://mindprod.com/jgloss/sizeof.html
http://www.jroller.com/maxim/entry/again_about_determining_size_of
http://yueyemaitian.iteye.com/blog/2033046
http://yueyemaitian.iteye.com/blog/2034305
http://rednaxelafx.iteye.com/blog/730461
http://stackoverflow.com/questions/11054548/what-does-the-usecompressedoops-jvm-flag-do-and-when-should-i-use-it


转载于:https://my.oschina.net/u/227422/blog/366683

对于长度一亿的数组进行去重且避免内存溢出,可以采用以下方法: ### 分块处理 将大数组分成多个小块,依次对每个小块进行去重操作,最后再合并这些小块。例如,每次处理 1000 个元素,这样能有效减少单次处理的数据量,降低内存压力。 ### 排序后去重 先对数组进行排序,相同的元素会相邻排列。然后遍历排序后的数组,只保留第一个出现的元素,跳过后续重复的元素。排序可以使用外部排序算法,如归并排序,它适合处理大规模数据。 以下是一个简单的 Python 示例代码: ```python def remove_duplicates(arr): arr.sort() result = [] prev = None for num in arr: if num != prev: result.append(num) prev = num return result # 示例用法 large_array = [1, 2, 2, 3, 4, 4, 5] unique_array = remove_duplicates(large_array) ``` ### 使用哈希表(需谨慎) 虽然哈希表(如 Python 的字典或 JavaHashMap)可以快速判断元素是否重复,但对于长度一亿的数组,可能会占用大量内存。可以考虑使用外部哈希表,将部分数据存储在磁盘上。 ### 布隆过滤器 布隆过滤器是一种空间效率极高的概率型数据结构,用于判断一个元素是否存在于一个集合中。它可以快速过滤掉大部分重复元素,减少后续处理的数据量。但布隆过滤器存在一定的误判率,即可能会误判某个元素存在于集合中。 ### 代码示例(Python 实现分块处理) ```python def chunked_remove_duplicates(large_array, chunk_size=10000000): unique_chunks = [] num_chunks = len(large_array) // chunk_size + (1 if len(large_array) % chunk_size != 0 else 0) for i in range(num_chunks): start = i * chunk_size end = min((i + 1) * chunk_size, len(large_array)) chunk = large_array[start:end] unique_chunk = list(set(chunk)) unique_chunks.extend(unique_chunk) final_unique = list(set(unique_chunks)) return final_unique # 示例用法 large_array = [1, 2, 2, 3, 4, 4, 5] * 10000000 unique_array = chunked_remove_duplicates(large_array) ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值