【问题标题】:Processing large arrays that do not fit in RAM in Java在 Java 中处理不适合 RAM 的大型数组
【发布时间】:2015-12-26 09:58:58
【问题描述】:

我正在开发一个文本分析程序,它将文档表示为某个预定义特征空间内的“特征计数”(例如,特定标记的出现)数组。这些数组经过一些处理后存储在一个 ArrayList 中。

我正在一个 64 mb 数据集上测试该程序,该数据集包含 50,000 条记录。该程序在小型数据集上运行良好,但现在当我开始将数组加载到 ArrayList 对象(使用 .add(double[]) 方法)时,它始终抛出“内存不足”Java 堆异常。根据我分配给堆栈的内存量,我将在 ArrayList 的第 1000 到第 3000 个添加时收到此异常,远远少于我的 50,000 个条目。我很清楚,我无法将所有这些数据存储在 RAM 中并像往常一样对其进行操作。

但是,我不确定哪种数据结构最适合允许我在整个数据集只有一部分可以加载到 RAM 时访问和执行计算?

我认为将数据序列化到磁盘并将位置存储在 RAM 中的哈希图中会很有用。不过,我也看到过关于缓存和缓冲处理的讨论。

我 100% 确定这是一个常见的 CS 问题,因此我确信有几种巧妙的方法可以解决这个问题。任何指针将不胜感激:-)

【问题讨论】:

  • 使用允许您查询一个小子集或执行一些其他分析(如运行函数或连接)并且支持游标(因此它不会将整个集合加载到内存中)或一些其他内存/映射缓存
  • @MadProgrammer 谢谢...内存映射的 IO 文件呢?
  • 之前没有(直接)使用过内存映射文件,很难说。我的基本担心是数据是否需要Serializable
  • "我开始将数组加载到 ArrayList 对象中" 您是要获取 List 还是 List?如果是后者,你将如何被稀疏数组保存?你不是。
  • @alamar 不,我的意思是 List 所以我需要存储的元素越少越好。

标签: java serialization mallet large-data


【解决方案1】:

你有很多选择:

  • 将堆大小 (-Xmx) 增加到几 GB。
  • 不要使用拳击集合,使用 fastutil - 这应该会减少 4 倍的内存使用。 http://fastutil.di.unimi.it/
  • 分批或按顺序处理数据 - 不要将整个数据集同时保存在内存中。
  • 使用适当的数据库。甚至还有像 HSQL 这样的进程内数据库,你的里程可能会有所不同。
  • 通过 map-reduce 处理您的数据,可能是像 pig 这样的本地工具。

【讨论】:

  • 谢谢!我尝试增加堆大小......不起作用。我正在考虑使用稀疏数组来减少存储空间,我会研究 fastutil。三是我的下一个选择。我喜欢进程内数据库的想法......也会考虑这一点。 MapReduce 可能有点矫枉过正,但它也是一种选择。
【解决方案2】:

使用Apache Spark(非常适合内存群集计算)?这将有助于将您的基础架构扩展,因为您的数据集变大。

【讨论】:

  • hmmm ......这将是一个可能永远无法到达10 tb的数据集的矫枉过正吗? span>
猜你喜欢
  • 2019-10-01
  • 2011-02-16
  • 2012-01-05
  • 1970-01-01
  • 2018-11-18
  • 2019-10-17
  • 2018-12-22
  • 2011-06-05
  • 1970-01-01
相关资源
最近更新 更多