减少非常大的HashMap的内存使用



我有一个非常大的哈希映射(200多万个条目),它是通过读取CSV文件的内容创建的。一些信息:

  1. HashMap将字符串键(少于20个字符)映射到字符串值(大约50个字符)。
  2. 这个HashMap初始化容量为300万,因此负载因子约为0.66。
  3. HashMap仅由单个操作使用,一旦该操作完成,我就"清除()"它。(虽然看起来这个清除实际上并没有清除内存,但是有必要单独调用System.gc()吗?)

我的一个想法是将HashMap更改为HashMap并使用字符串的hashCode作为键,这将最终节省一点内存,但如果两个字符串具有相同的哈希码,则存在冲突的风险问题…对于长度小于20个字符的字符串,这种情况发生的可能性有多大?

还有人有什么主意吗?CSV文件本身只有100 MB,但是java最终为这个HashMap使用了超过600MB的内存。

谢谢!

听起来您已经有了尝试这个的框架。而不是添加字符串,添加string.hashCode(),看看你是否得到碰撞。

在释放内存方面,JVM通常不会变小,但如果需要的话,它会进行垃圾收集。

而且,听起来你可能有一个根本不需要哈希表的算法。你能更详细地描述一下你想做的事情吗?

解析CSV,并构建一个Map,其键是您现有的键,但值是指向该键在文件中的位置的Integer指针。

当您想要一个键的值时,在映射中找到索引,然后使用RandomAccessFile从文件中读取该行。在处理过程中保持RandomAccessFile打开,然后在完成时关闭它。

您要做的正是一个JOIN操作。尝试考虑像H2这样的内存DB,您可以通过将两个CSV文件加载到临时表中,然后对它们执行JOIN操作来实现这一点。根据我的经验,h2在加载操作下运行得很好,这段代码肯定会比我们手动的基于HashMap的连接方法更快,内存占用更少。

如果性能不是主要考虑的问题,可以将条目存储在数据库中。那么内存就不是问题了,多亏了数据库,你的搜索速度就算不是很好,也很好。

最新更新