【问题标题】:Remove unused allocated Memory from HashMaps从 HashMap 中删除未使用的分配内存
【发布时间】:2011-05-10 18:22:31
【问题描述】:

我想读取一些 XML 文件并将其转换为图形(没有图形,只是一个模型)。但由于文件非常大(2.2 GB),我保存所有信息的模型对象变得更大(文件大小的 4 倍......)。

在网上搜索我试图找到减小对象大小的方法。我尝试了不同的集合类型,但想坚持使用 HashMap(因为我必须随机访问)。实际的键和值只占分配内存的一小部分。大部分哈希表是空的...

如果我没有完全错,垃圾回收并不能帮助我释放分配的内存并减少哈希图的大小。是否有其他方法可以释放未使用的内存并缩小哈希图?或者有没有办法进行完美的散列?还是我应该只使用另一个集合?

提前致谢,

塞巴斯蒂安

【问题讨论】:

  • 这里改进的关键是避免一次将所有 2.2 GB 文件读入内存

标签: java memory hashmap garbage


【解决方案1】:

HashMap 通常只是填充到一定容量百分比的大型引用数组。如果只有 80% 的地图被填充,则剩余 20% 的数组单元格未被使用(即为空)。额外的开销实际上只是空(null)单元格。

在 32 位 CPU 上,每个数组单元的大小通常为 4 个字节(尽管某些 JVM 实现可能会分配 8 个字节)。总体而言,未使用的空间并没有那么多。

地图填满后,您可以将其复制到另一个HashMap,尺寸更合适(更小),填充百分比更大。

您的问题似乎暗示您担心有更多已分配但未使用的对象。但这是怎么回事呢?

附录

一旦映射几乎被填满(通常超过 95% 左右),就会分配一个更大的数组,将旧数组的内容复制到新数组,然后将较小的数组留作垃圾回收。这显然是一项昂贵的操作,因此为地图选择一个合理的大初始大小是提高性能的关键。

如果您可以(过度)估计所需的单元格数量,则预分配地图可以减少甚至消除调整大小操作。

【讨论】:

  • 当调整数组大小时,将调整为旧大小的两倍。在最坏的情况下,只有一个项目导致分配一个巨大的数组。
  • TreeSet 的增长可能更可预测(尽管完美的 HashMap 很容易比完美的 TreeMap 小得多)。问题是几乎不可能得到一个甚至接近完美的 HashMap(从内存占用)。
【解决方案2】:

你问的不是很清楚,不清楚内存是由你放在 hasmap 中的对象还是由 hashmap 本身占用的,因为它只保存引用,所以不应该是这种情况。

无论如何,看看WeakHashMap,也许这就是你要找的东西:它是一个不保证密钥保存在其中的哈希图,它应该用作一种缓存,但是从你的描述中我真的不知道是不是你的情况。

【讨论】:

  • 已经试过了。它确实使用了更少的内存,但 GC 似乎丢弃了我稍后需要的对象:(
【解决方案3】:

如果您在减少哈希映射的内存占用方面无济于事,您总是可以将数据放入数据库中。根据访问数据的方式,如果您在 db 前面引入缓存,您仍然可以获得合理的性能。

【讨论】:

    【解决方案4】:

    可能会起作用的一件事是,您可能有引用旧的较大字符串的子字符串,然后这些子字符串使 GC 无法收集太大的 char 数组。

    当您使用一些将属性/值作为子字符串从较大字符串返回的 XML 解析器时,会发生这种情况。 (子字符串只是较大字符串的有限视图)。

    尝试通过执行以下操作将您的字符串放入地图中:

    map.put(new String(key), new String(value));
    

    请注意,当您填充映射时,GC 可能需要做更多的工作,如果您没有那么多引用较大字符串的子字符串,这可能对您没有帮助。

    【讨论】:

      【解决方案5】:

      如果你真的很认真,有时间的话,可以根据minimal perfect hashing自己实现Map接口

      如果您的键是字符串,那么显然有一个可供您使用的映射here。 我自己没有尝试过,但它吹嘘减少了内存使用量。

      【讨论】:

        【解决方案6】:

        您可以试一试the Trove collections。他们将其宣传为 java.util Collections 的更节省时间和空间的替代品。

        【讨论】:

          猜你喜欢
          • 2018-03-25
          • 1970-01-01
          • 2012-05-10
          • 1970-01-01
          • 2015-01-18
          • 2011-09-13
          • 2013-12-27
          • 2011-06-17
          • 1970-01-01
          相关资源
          最近更新 更多