【问题标题】:Read big text file to HashMap - heap overflow将大文本文件读取到 HashMap - 堆溢出
【发布时间】:2012-10-16 01:55:03
【问题描述】:

我正在尝试将文本文件中的数据放入 HashMap。 文本文件的格式如下:

它有大约 700 万行...(大小:700MB)

所以我要做的是: 我读了每一行,然后我把绿色的字段连接成一个字符串 这将是 HashMap 键。值将是红色区域。

每次我读到一行时,我都必须检查 HashMap 是否已经有一个带有此类键的条目, 如果是这样,我只是更新值与红色相加; 如果没有,则向 HashMap 添加一个新条目。

我用 70.000 行的文本文件尝试了这个,效果很好。

但现在有了 700 万行文本文件,我遇到了“java 堆空间”问题,如图所示:

这是因为 HashMap 吗? 是否可以优化我的算法?

【问题讨论】:

  • 要存储 700 MB 的文本,您将需要至少 1.4 GB 可能接近 3 GB 的开销和 HashMap。你有多少内存?
  • 注意,你不需要先检查是否有条目,如果条目已经在HashMap中,它将被替换为新的值。
  • 我刚刚将我的 netbeans.conf 更改为 -J-Xms500M -J-XX:PermSize=1500M 我会尝试这样并检查一下...顺便说一下我有 4GB 的 RAM
  • 所以我这样做了:-J-Xms600M -J-XX:PermSize=1600M...但仍然有堆溢出,如果我向 Xms 添加更多内容,Netbeans 将无法启动... :(
  • 你需要这么多数据做什么?大数据的最佳管理方法是分段读取,并且只将相关的小部分存储在内存中。您可以创建一个 API 来仅读取大量数据中所需的一小部分,而将其余部分保存在磁盘中。您可以让 API 返回这些小部分的 HashMap,然后使用 HashMap。如果要读取和处理整个文件,请在文件部分重复从 API 请求 HashMap,从内存中丢弃已处理的部分。

标签: java hashmap text-files heap-memory


【解决方案1】:

你应该增加你的堆空间

-Xms<size>        set initial Java heap size
-Xmx<size>        set maximum Java heap size

java -Xms1024m -Xmx2048m

阅读不错From Java code to Java heap

Table 3. Attributes of a HashMap
Default capacity                     16 entries
Empty size                           128 bytes
Overhead                             64 bytes plus 36 bytes per entry
Overhead for a 10K collection   ~    360K
Search/insert/delete performance    O(1) — Time taken is constant time, regardless of the number of elements (assuming no hash collisions)

如果您考虑7 Million 记录的上述表开销大约为246 MB,那么您的最小堆大小必须在1000 MB 左右

【讨论】:

  • 我刚刚将我的 netbeans.conf 更改为 -J-Xms500M -J-XX:PermSize=1500M 我会尝试这样并检查一下...
  • 那么,我应该尝试除 HashMap 之外的其他结构吗?因为每行我需要检查这样的条目是否已经存在,所以使用 hashmap 我避免使用搜索算法......
  • @javardo 你不需要检查条目是否存在,如果条目存在,HashMap 将用新值替换条目。
  • 是的,AmitD,但如果有条目,我还需要将新行的“红色”值与 HashMap 中的值相加。因为如果不是,我只是添加一个带有“红色”值的新条目。
  • @javardo 像这样? :pastebin.com/b3GB6PS0 最后你应该有一个地图,绿色字符串作为键,红色整数的总和作为值。
【解决方案2】:

除了更改堆大小之外,还可以考虑通过将键存储为打包二进制而不是字符串来“压缩”(编码)键。

每个 IP 地址可以存储为 4 个字节。端口号(如果是这样的话)每个是 2 个字节。协议可能存储为一个字节或更少。

这是 13 个字节,而不是存储为 UTF16 字符串的 70 个字节,如果我的数学在晚上这个时候是正确的,那么键的内存会减少 5 倍...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-02
    • 1970-01-01
    • 1970-01-01
    • 2011-03-30
    相关资源
    最近更新 更多