【发布时间】:2012-01-24 16:07:05
【问题描述】:
c++和java中hashmap/map对象的最大尺寸是多少?我想使用 hashmap,但我正在处理大量数据。我担心如果我在大数据上使用它,它可能会因为容量限制而崩溃。是这样吗?如果是这样,还有什么替代方法?
【问题讨论】:
-
你考虑过使用数据库吗?
c++和java中hashmap/map对象的最大尺寸是多少?我想使用 hashmap,但我正在处理大量数据。我担心如果我在大数据上使用它,它可能会因为容量限制而崩溃。是这样吗?如果是这样,还有什么替代方法?
【问题讨论】:
在 Java 中,HashMap 的 size() 属于 int 类型,因此映射中有 2^31-1 个元素的上限。
在 C++ 中,map::max_size 返回最大值。元素的数量。在 vanilla 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 时,您会失去哈希图的速度优化。每次你去硬盘驱动器都会导致延迟(寻找时间等)。搜索存储在磁盘上的 hashmap 变成了线性时间。
我想说的是,如果您的数据无法放入内存,那么地图将毫无用处。
更好的解决方案是索引您的数据。将索引存储在内存中,并有一个指针指向您要查找的数据在磁盘上的位置。从磁盘检索数据。
通过使用 RAID 进行存储进一步改进此模型。 转到 DB 也会导致与转到 HDD 相同的延迟。
我建议您将所有值存储在数据库中,并保留一个以哈希为键的内存字典。
【讨论】:
在 Java 中,Hashmap 的大小受 JVM 内存的限制。它可以变大。据我所知,没有硬性限制。
不懂 C++。
【讨论】:
int 的最大值,因为这是size() 的返回类型。
没有明确的最大大小 - 这取决于您的平台和 STL 的实现。例如,如果您有高度碎片化的内存并且实现使用连续缓冲区(我怀疑这是因为通常只有向量会这样做),那么您可能会在计算机内存耗尽之前就用完空间。
或者,如果在实现中随着容器扩展而分配小块,则您的内存限制是您的计算机拥有的内存以及您在操作系统中设置的限制的组合(如果 ulimit 恰好设置在Linux 或任何 Windows 变体)。
该类确实有一个 max_size() 成员函数,但如果你没有设置它应该不会影响你。所以,简单的答案 - 除了那些依赖于您自己的计算机和操作系统的限制之外,没有限制。
【讨论】:
您实际上将受到系统内存容量的限制。
如果您使用的是海量数据,请考虑这些海量数据的来源。并以一种将大量数据留在原处的方式设计您的地图。
【讨论】:
Java 或 C++ 本身不是限制。在实践中,您只受到资源的限制。
根据您的要求,方法可能是:
尝试查看here 以获得一些提示。
【讨论】: