在循环中运行sql时的java内存管理
我在内存管理方面遇到了一些问题。我这里有一些代码,它在循环中运行sql查询,将数据放入数组列表,然后进行一些计算。我以前运行过许多类似的程序,但没有这个问题。我将查询放在循环中的原因是,不会在java对象中同时存储太多内存。然而,现在当我运行程序时,每次都会在完全相同的位置(在循环的第29次迭代时)出现内存错误 以下是错误-在循环中运行sql时的java内存管理,java,memory,Java,Memory,我在内存管理方面遇到了一些问题。我这里有一些代码,它在循环中运行sql查询,将数据放入数组列表,然后进行一些计算。我以前运行过许多类似的程序,但没有这个问题。我将查询放在循环中的原因是,不会在java对象中同时存储太多内存。然而,现在当我运行程序时,每次都会在完全相同的位置(在循环的第29次迭代时)出现内存错误 以下是错误- Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at java.util.Ar
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Unknown Source)
at java.util.Arrays.copyOf(Unknown Source)
at java.util.ArrayList.grow(Unknown Source)
at java.util.ArrayList.ensureCapacityInternal(Unknown Source)
at java.util.ArrayList.add(Unknown Source)
at transnMat.bootTrnsn.main(bootTrnsn.java:82)
我已经粘贴了下面的代码,我真的很感激任何关于我可能会改变以摆脱此问题的提示-
Connection conn = null;Statement st = null;ResultSet rstru = null;
for(int i=start;i<stop;i++) {
double[][] forvariance = new double[(demos.length-1)][numsims];
ArrayList<Long> hhids1 = new ArrayList<>();
ArrayList<Double> outlierwt = new ArrayList<>();
ArrayList<String> fbdemos = new ArrayList<>();
ArrayList<String> trudemos = new ArrayList<>();
rstru = st.executeQuery(
"select TRUTH_DEMO_ID, FB_DEMO_ID, RN_ID, OUTLIER_WEIGHT from SCRATCH.." +
months + "monthtable where BRAND_ID = " + brands[i] +
" order by RN_ID");
while (rstru.next()) { //Get query results and put them into a hash map.
String temp0 = rstru.getString(1);
String temp1 = rstru.getString(2);
String temp2 = rstru.getString(3);
String temp3 = rstru.getString(4);
//String temp5 = rstru.getString(6);
hhids1.add(Long.parseLong(temp2.substring(0,11)));
fbdemos.add(temp1);
trudemos.add(temp0);
outlierwt.add(Double.parseDouble(temp3));
}
for(int sim=0;sim<numsims;sim++) {
trnsnpv = new double[demos.length][demos.length-1];
HashMap<Long,Integer> thissampl = bootsampl2.get(sim);
for(int i1=0;i1<fbdemos.size();i1++) {
if(thissampl.containsKey(hhids1.get(i1)))
trnsnpv[dems.get(fbdemos.get(i1))][dems.get(trudemos.get(i1))-1] +=
outlierwt.get(i1)*(double)thissampl.get(hhids1.get(i1));
}
for(int j=0;j<trnsnpv.length;j++) { //27 rows
trnsnpv[j] = normalize(trnsnpv[j]);
for(int k=0;k<trnsnpv[j].length;k++) { //26 columns
forvariance[k][sim] += trnsnpv[j][k];
}
}
}
for(int k = 0; k < (demos.length - 1); k++) {
double d = StdStats.var11(forvariance[k]);
fileIO.fileIO.write2file(brands[i] + "," + demos[k+1] +
"," + String.valueOf(d) + "\n", "vars.csv");
}
System.out.println("Brands processed: " + String.valueOf(i-start) +
" out of: " + (stop-start));
hhids1.clear();
outlierwt.clear();
fbdemos.clear();
trudemos.clear();
}
连接连接=null;语句st=null;ResultSet rstru=null;
对于(int i=start;i这里有几个性能问题:
<> LI>数据库必须每次重新编译查询,因为SQL没有参数化。请考虑使用准备好的语句。
嵌套循环。我看到一个点,其中有4个嵌套循环
由于变量名和过度循环,我无法确定您的逻辑在做什么。如果可能,并且不确定是否与您的逻辑一致(取决于您正在进行的聚合),您能否在while(rs.next())循环中一次只处理一个对象
例:
下面是代码的版本,它确实有效(供我自己参考)
用于(int i=start;i尝试使用更多堆内存来执行程序。您是否尝试过使用-Xmx…
来增加堆空间?也许您的JVM只需要更多内存。此外,您在尝试增加支持ArrayList
的数组的大小时失败了,这将使内存需求增加了一倍以上。您应该为arraylist分配足够的空间,这样它就不需要增加。伙计们,谢谢你们的快速回复。问题是我以前(在同一个数据库上)运行过类似的程序,没有内存问题(并且需要增加堆大小).不过,我以前确实没有使用数组列表。我在这里使用数组列表的原因是我不知道查询将返回多少数据。Jim-如何为arraylist分配空间?进行两次查询。首先选择count(*),然后你知道。l=new arraylist(100)将创建一个包含100项的数组列表。此时,您可以使用数组,这将节省您的空间。您也不必提及查询返回的行数。谢谢Brandon。我没有将所有内容都放在while循环中,但其中有些内容。我更改了周围的数据结构,因此不必存储数组还有一件事——我认为嵌套循环是不可避免的;但我还是一个初学者,不明白第1点的意思。你能解释一下“数据库必须重新编译查询”吗。在循环中每次都是不同的查询。我以前从未使用过预处理语句。这会使代码更快吗?维基百科关于预处理语句的文章对此有很好的解释。基本上,当数据库接收到查询时,它会对其进行大量分析。如果可以输入占位符变量,dat阿巴斯可以重复使用这项工作。
while (rs.next()) {
String temp0 = rstru.getString(1);
String temp1 = rstru.getString(2);
String temp2 = rstru.getString(3);
String temp3 = rstru.getString(4);
//String temp5 = rstru.getString(6);
// do all of your work in here, so that your objects
// can be garbage collected before the next iteration
}
for(int i=start;i<stop;i++){
double[][] forvariance = new double[(demos.length-1)][numsims];
trnsnpv = new double[numsims][demos.length][demos.length-1];
int size = 0;
Long hhids1;
Double outlierwt;
String fbdemos;
String trudemos;
rstru = st.executeQuery("select TRUTH_DEMO_ID, FB_DEMO_ID, RN_ID, OUTLIER_WEIGHT from SCRATCH.."+months+"monthtable where BRAND_ID = " + brands[i]+" order by RN_ID");
while (rstru.next()) {//Get query results and put them into a hash map.
String temp0 = rstru.getString(1);String temp1 = rstru.getString(2);String temp2 = rstru.getString(3);String temp3 = rstru.getString(4);
hhids1 = (Long.parseLong(temp2.substring(0,11)));
fbdemos = (temp1);
trudemos = (temp0);
outlierwt = (Double.parseDouble(temp3));
for(int sim=0;sim<numsims;sim++){
HashMap<Long,Integer> thissampl = bootsampl2.get(sim);
if(thissampl.containsKey(hhids1))
trnsnpv[sim][dems.get(fbdemos)][dems.get(trudemos)-1] += outlierwt*(double)thissampl.get(hhids1);
}
size++;
}
System.out.print("Processing: " + size + " rows");
for(int sim=0;sim<numsims;sim++){
for(int j=0;j<trnsnpv[sim].length;j++){//27 rows
trnsnpv[sim][j] = normalize(trnsnpv[sim][j]);
for(int k=0;k<trnsnpv[sim][j].length;k++){//26 columns
forvariance[k][sim] += trnsnpv[sim][j][k];
}
}
}
for(int k = 0; k < (demos.length - 1); k++){
double d = StdStats.var11(forvariance[k]);
fileIO.fileIO.write2file(brands[i] + "," + demos[k+1] + "," + String.valueOf(d) + "\n", "vars.csv");
}
System.out.print("Brands processed: " + String.valueOf(i-start + 1 ) + " out of: " + (stop-start) + "\n");
//hhids1.clear();outlierwt.clear();fbdemos.clear();trudemos.clear();
}