在C++和Java中,哈希映射/映射对象的最大大小是多少?我想使用哈希映射,但我正在处理庞大的数据。我担心如果我在大数据上使用它,由于容量限制而导致崩溃。是这样吗?如果是,有什么替代方法吗?
HashMap
的size()
是int
类型,因此地图中的元素数量上限为2^31-1个。map::max_size
返回元素的最大数量。在一个普通的map
中,最多只能有SIZE_T_MAX
个元素,这在现代硬件上是2^64-1。在C++中,std::map
有一个max_size()
成员函数(对应它可以容纳的数据量)。
sizeof(std::map<...>)
会给你实际对象的大小(对应实际对象的大小,而不是它所持有的数据)。
std::map和hashmap是动态结构。它们随着元素的添加而增长,直到系统能够为它们提供内存。
max_size()成员函数给出了类实现(在代码中)能够支持的上限,但该限制通常比代码本身运行的系统容量要宽。
系统可用内存还取决于系统除了运行您的应用程序之外还在做什么。
您可以通过查询操作系统有关其可以为进程提供的空闲内存量并将其除以一个元素的大小来经验性地得出一个合理的数字,该元素为“键加值再加一些开销(通常为20/24字节)”。
对于Java:
HashMap的底层存储是一个大小始终为2的幂次方的数组。最大大小可以达到2^30。默认负载因子为0.75,它将尝试在大约7.5亿个条目时进行增长并失败。
TreeMap没有限制,可以有超过2^31个条目(但size()将返回MAX_VALUE)。ConcurrentSkipList和ConcurrentHashMap同样如此。
需要记住的一些信息(大局观):
如果您的数据很大,无法将其保存在内存中。您必须转到二级存储:HDD。当您转到HDD时,会失去哈希映射的速度优化。每次访问HDD都会产生延迟(搜索时间等)。在磁盘上存储的哈希映射的搜索变成了线性时间。
我的意思是,如果您的数据无法放入内存,则地图无用。
更好的解决方案是对数据进行索引。将索引存储在内存中,并具有指向所需数据在磁盘上位置的指针。从磁盘检索数据。
通过使用RAID进行存储来进一步改善此模型。访问数据库也会导致与访问硬盘驱动器相同的延迟。
我建议您将所有值存储在数据库中,并使用哈希作为键保留一个内存字典。
int
的最大值,因为 size()
的返回类型是 int
。 - Fred Foo没有显式的最大大小 - 这取决于您的平台和STL的实现。例如,如果您具有高度分散的内存,并且实现使用连续的缓冲区(我怀疑,因为通常只有向量才这样做),那么您可能会在计算机内存耗尽之前就耗尽空间。
或者,如果容器在实现中扩展时分配小块,则您的内存限制是计算机拥有的内存和您在操作系统中设置的限制的组合(如果在Linux中设置了ulimit,或者在Windows中与此相当)。
该类确实具有max_size()成员函数,但如果您没有设置它,则不应影响您。因此,简单的答案是 - 除了依赖于您自己的计算机和操作系统的限制外,没有限制。
你的系统内存容量将会是你的限制因素。
如果你正在处理大数据,请考虑这些大数据来自哪里。并设计你的映射方式,让大数据保留在原地。
Java或C++本身并不是限制。在实践中,您只受资源的限制。
根据您的要求,可能会有以下方法:
请尝试查看此处获取一些提示。