【发布时间】:2017-01-12 08:13:21
【问题描述】:
当您需要相互比较 2 个非常大的数组列表时,正确的方法是什么?
这些数组列表的大小都是 100,000 个项目,并且在简单地比较每个项目时肯定会崩溃。
for (CItem c : cItems) {
for (CItem r : rItems) {
if (c.getID().equals(r.getID())) {
Mismatch m = compareItems(c, r);
if (m != null) {
mismatches.add(m);
}
}
}
}
现在我不能 100% 确定垃圾收集在这种情况下是如何工作的,但我们得到的错误是:
java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOfRange(Arrays.java:3664) ~[na:1.8.0_73]
at java.lang.String.<init>(String.java:207) ~[na:1.8.0_73]
at java.lang.StringBuilder.toString(StringBuilder.java:407) ~[na:1.8.0_73]
和
java.lang.OutOfMemoryError: GC overhead limit exceeded
at java.util.Arrays.copyOf(Arrays.java:3181) ~[na:1.8.0_73]
at java.util.ArrayList.grow(ArrayList.java:261) ~[na:1.8.0_73]
at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:235) ~[na:1.8.0_73]
at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:227) ~[na:1.8.0_73]
at java.util.ArrayList.add(ArrayList.java:458) ~[na:1.8.0_73]
到目前为止可能的解决方案是
- 将每个列表拆分为最多 x 个项目并比较这些多个列表(有点复杂)
- 创建一个新数据库并查询每个项目(这会很慢而且现在不可行)
- 购买 200 GB 内存
我们将不胜感激。
【问题讨论】:
-
问题不在于您的比较,而是在发现不匹配时添加到新的 ArrayList
-
什么是 compareItems(c, r) ?
-
您可以尝试打印在异常之前添加了多少项目吗?
-
其中一个列表中可以包含多少个具有相同 id 的项目?嵌套循环方法看起来也很昂贵,如何按 id 对列表进行排序,然后一次性遍历它们呢?
-
200000 个项目不是问题。
100000*100000是。
标签: java arraylist out-of-memory