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

时间:2011-07-18 18:21:20

标签: java memory memory-management memory-leaks hashmap

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

  1. HashMap将String键(少于20个字符)映射到String值(大约50个字符)。
  2. 初始化此HashMap的初始容量为300万,因此负载系数约为0.66。
  3. HashMap仅由单个操作使用,一旦完成该操作,我就“清除()”它。 (虽然看起来这种清除实际上并没有清除内存,但需要单独调用System.gc()吗?)。
  4. 我的一个想法是将HashMap更改为HashMap并使用String的hashCode作为键,这将最终节省一点内存,但如果两个字符串具有相同的哈希码,则存在冲突问题...如何对于长度小于20个字符的字符串,这可能是这样吗?

    有没有其他人对这里做什么有任何想法? CSV文件本身只有100 MB,但是对于这个HashMap,java最终会在内存中使用超过600MB。

    谢谢!

4 个答案:

答案 0 :(得分:1)

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

如果需要键的值,请在映射中查找索引,然后使用RandomAccessFile从文件中读取该行。在处理过程中保持RandomAccessFile处于打开状态,然后在完成后关闭它。

答案 1 :(得分:1)

你要做的只是一个JOIN操作。尝试考虑像H2这样的内存数据库,你可以通过将两个CSV文件加载到临时表然后对它们进行JOIN来实现这一点。 根据我的经验,h2在加载操作时运行良好,而且这个代码肯定比基于手动HashMap的连接方法更快,内存更少。

答案 2 :(得分:0)

如果性能不是主要问题,请将条目存储在数据库中。然后记忆不是问题,而且由于数据库的存在,你的搜索速度也很好(如果不是很好的话)。

答案 3 :(得分:0)

听起来你已经有了尝试这个的框架。不是添加字符串,而是添加string.hashCode()并查看是否发生冲突。

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

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