我正在尝试在内存中加载一个包含1400万行哈希表的大文件。每行包含三个数字(n,m,v),其中:
每个用户n
都有一个hashtable<item, rate>
来存储用户评分的项目,
并且每个项目都有一个hashtable<user, rate>
来存储评价此项目的用户。
在我的机器上,我无法将此结构加载到内存中,因此每次都会出现堆内存错误。
我尝试用hashBasedTable替换hashtables,它允许每个值的两个键,但没有解决方案。另外hashBasedTable让我的程序慢得多。
是否有任何解决方案可以加载大量数据?
答案 0 :(得分:2)
每三千万行三个数字听起来不像一个海量数据阵列。 大约是14M *(3 + 1)* 8~450M或记忆。
只需确保将-Xmx设置为足够大的值(例如-Xmx1024m - 这将允许JVM分配最多1G的RAM)。
P.S。我会建议HashMap
而不是HashTable
。
答案 1 :(得分:1)
我建议您分别使用ArrayList<User>
和ArrayList<Item>
代表每个评分项目的用户和每个用户的评分项目。这将节省大量空间。
不可否认,某些操作现在为O(N)
,但如果N
变大,则只会出现问题。 (如果确实如此,请考虑混合使用ArrayList
表示小关系,HashMap
表示大关系。)
建议#2 - 使用普通数组...并对它们进行排序,以便您可以使用二进制搜索实现查找。这是代码密集型(即更复杂),但它会比使用Collection类型更好地使用内存。
建议#3 - 使用数据库。它会更好地扩展。
答案 2 :(得分:0)
我认为这取决于您使用的数据结构。你根本无法将如此多的数据加载到RAM中,你必须逐行处理文件并执行你拥有的逻辑。
答案 3 :(得分:0)
我对你的访问模式有点不清楚,但听起来你可能想要使用一个大表而不是每个用户和每个项目一个。特别是如果您的数据非常稀疏(每个用户只有少数项目,反之亦然),由于哈希表的初始容量,您将浪费大量空间(您可以尝试降低初始容量和/或提高加载因子)如果你想保留现有的组织。)
构建一个pair对象(用户id,item id),用作单个大哈希表的键。如果您需要枚举(即列出用户的所有项目,反之亦然),请保留该数据的ArrayList
并使用trimToSize
,比哈希表更紧凑。