2

我正在尝试在内存中的哈希表中加载一个包含 1400 万行的大文件。每行包含三个数字 (n,m,v),其中:

  • n:是用户的id(一个对象)
  • m:是一个项目(一个对象)的id
  • v: 是用户 n 给项目 m 的费率。

每个用户n都有一个hashtable<item, rate>存储用户评价的项目,每个项目都有一个hashtable<user, rate>存储用户评价这个项目的用户。

在我的机器上,我无法将此结构加载到内存中,因此每次都会出现堆内存错误。

我试图用 hashBasedTable 替换哈希表,它允许为每个值提供两个键,但没有解决方案。此外 hashBasedTable 使我的程序慢得多。

有什么解决方案可以加载这么多数据吗?

4

4 回答 4

2

1400 万行,每行三个数字听起来不像是一个庞大的数据阵列。它大约是 14M * (3 + 1) * 8 ~ 450M 或内存。

只需确保将 -Xmx 设置设置为足够大的值(例如 -Xmx1024m - 这将允许 JVM 分配高达 1G 的 RAM)。

PS我会建议HashMap而不是HashTable

于 2012-10-28T02:52:18.947 回答
1

我建议您分别使用ArrayList<User>and来代表每个评分项目的用户和每个用户的评分项目ArrayList<Item>。这将节省大量空间。

诚然,现在会有一些操作,O(N)但只有在N变大时才会出现问题。(如果是这样,请考虑使用混合ArrayList关系来处理小型关系和HashMap大型关系。)

建议#2 - 使用普通数组......并保持它们排序,以便您可以使用二进制搜索实现查找。这是更密集的代码(即更复杂),但它会给你比使用集合类型更好的内存使用。

建议#3 - 使用数据库。它将更好地扩展。

于 2012-10-28T03:10:24.350 回答
0

我不认为这取决于您使用的数据结构。您根本无法将这么多数据加载到 RAM 中,您必须逐行处理文件并执行您拥有的逻辑。

于 2012-10-28T02:28:13.263 回答
0

我对您的访问模式有点不清楚,但听起来您可能想要使用一个大表而不是每个用户和每个项目一个。特别是如果您的数据非常稀疏(每个用户只有几个项目,反之亦然),由于哈希表的初始容量,您将浪费大量空间(您可以尝试降低初始容量和/或提高负载因子如果您想保留当前的组织)。

构建一个配对对象(用户 ID,项目 ID)用作单个大哈希表的键。如果您需要枚举(即列出用户的所有项目,反之亦然),请保留ArrayList该数据的 s 并使用trimToSize,这比哈希表更紧凑。

于 2012-10-28T02:59:13.157 回答