在以下场景中需要有效内存管理方面的帮助。我从两个不同的数据库中获取数据并比较Java中的数据。(目前使用两个查询在单个数据库上进行测试)。
由于需要比较980万条记录,我每次都要复制50k条记录并加载到ArrayList中并使用Binarysearch进行比较。虽然我在每次迭代后清除(分配给null并运行gc)arraylist,但是在比较了250万条记录后,我得到了堆空间错误(分配1GB RAM)。
我的查询中的内存泄漏在哪里?
Query1= select empno,ename from table1 order by empno;
Query2= select empno,ename from table2 order by empno;
ResultSet rs1 = st1.executeQuery(query1);
ResultSet rs2 = st2.executeQuery(query2);
for (;;) {
ArrayList<String> al = new ArrayList<String>();
ArrayList<String> al1 = new ArrayList<String>();
if (totalRecords1 == Ubound)
break;
Lbound = Ubound + 1;
Ubound = min(Ubound + 50000, totalRecords1);
System.out.println("Lbound : " + Lbound);
System.out.println("Ubound : " + Ubound);
for (int i = Lbound; i <= Ubound; i++) {
recordConcat1 = ""; recordConcat2 = "";
String recordConcat1 = "", recordConcat2 = "";
rs1.next();
rs2.next();
recordConcat1 = recordConcat1 + rs1.getString(z) + " ǀ ";
recordConcat2 = recordConcat2 + rs2.getString(z) + " ǀ ";
al.add(recordConcat1);
al1.add(recordConcat2);
} /* End of First Lap */
System.out.println("End of Lap : "+lap++);
int index =0;
for(int like=0;like<al.size();like++) {
if(Collections.binarySearch(al1,al.get(like))>=0)
continue;
else {
System.out.println("Not matched : "+ al.get(like));
break;
}
}
al =null;
al1=null;
System.gc();
} /* End of Infinite Loop */
答案 0 :(得分:0)
而不是将ArrayLists设置为null并调用GC。调用ArrayList.clear()这不会释放ArrayLists的内存但重用它。此外,因为您有一个固定的上限为50000,所以将该数字传递给ArrayList的构造函数以避免动态内存重新分配,同时自动将ArrayLists从其默认初始大小10开始增长。
另一方面,如果我正确阅读,你想要实现的是告诉一个表的每个元素是否在另一个表中。因为数据是排序的,所以可以在不将块加载到内存中而是并行读取两个ResultSet的情况下执行此操作。
我认为即使没有内存不足错误,您的算法也无法正常工作。你从表A读取50K,从表B读取50K。现在在块A上搜索块B的每个元素。但是如果B的前50000中的元素位于A的位置50001,那该怎么办?你会认为它是&#39不存在但实际上却存在。正确?