【发布时间】:2016-07-06 19:14:18
【问题描述】:
我有一个项目正在处理正在写入 Excel 文件的大量数据。我将这些数据以Map<List<String>, Integer> 的形式存储在一个静态HashMap 中,其中列表的大小只有3。然而,Map 中的条目数可以在0 到11,300 之间。
这个项目的流程是:
用条目加载地图
迭代地图并做一些事情
- 为下一组条目清除地图
我最近发现的关于 HashMap 的一点是,当超出设定的大小时它会如何重新调整大小。因此,我的地图不仅会不断地以惊人的长度重新调整大小,而且当我清除最大的条目集时,它很可能有大约 20,000 个空条目。
所以我正在尝试对这件事进行微优化,但我陷入了如何做到这一点的两难境地。我的两个想法是:
将初始 HashMap 的默认值设置为允许它最多只调整一次大小的值
使用每个新条目的预期平均大小重新初始化 HashMap,以限制重新调整大小并允许垃圾收集器进行一些清理
我的直觉告诉我选项 2 可能是最合理的选项,但这仍然可以证明根据下一个条目集重新调整大小。但是选项一极大地限制了一次操作的重新调整大小,但随后给我留下了数以千计的空条目。
我提出的两种解决方案中的一种是否比另一种更好,两者在内存改进方面没有太大差异,还是我监督过其他一些解决方案(不涉及更改数据结构)?
编辑:仅在某些情况下,我想这样做是因为偶尔项目会耗尽堆内存,我正在尝试确定这个巨大的地图现在或可能产生的影响有多大。
EDIT2:为了澄清,地图本身的大小是较大的值。密钥大小(即列表)只有 3。
【问题讨论】:
-
不要执行选项 2。如果您有足够的内存来处理最坏的情况,即 11300
List对象作为映射的键,那么您就有足够的内存用于整个过程。缩小地图并没有真正获得任何收益,但是重新扩展会损失性能。与其他所有情况相比,缩小所节省的内存是最小的。这是或当然假设它是一个持续的过程。不要在不使用它的情况下长时间保留大而空的地图。在这种情况下,请移除地图并重新分配它。 -
有什么理由不能使用 TreeMap?我认为它不会明显变慢(log_2(11300) 只有 13),并且不会浪费任何空间。
-
@Oliver 映射键是
List,不是Comparable,阻止使用TreeMap。可以提供自定义的Comparator,但是您仍然必须决定列表的顺序,这可能不可行。此外,TreeMap在峰值时比HashMap使用更多的内存。 -
你的记忆力有那么大吗?您的应用程序是否在极低端或嵌入式系统上运行?或者它必须能够在一个小容器内运行?地图中的 20000 个条目几乎不是现代台式机甚至智能手机上的堆用完的原因。
-
@Leon 我在本地机器上的内存并没有那么受限,但是我运行我的应用程序的服务器可能有也可能没有很多东西可以玩,这就是为什么我不只是将堆大小提高到 3GB
标签: java memory-management hashmap