在循环中运行sql时的java内存管理

在循环中运行sql时的java内存管理,java,memory,Java,Memory,我在内存管理方面遇到了一些问题。我这里有一些代码,它在循环中运行sql查询,将数据放入数组列表,然后进行一些计算。我以前运行过许多类似的程序,但没有这个问题。我将查询放在循环中的原因是,不会在java对象中同时存储太多内存。然而,现在当我运行程序时,每次都会在完全相同的位置(在循环的第29次迭代时)出现内存错误 以下是错误- Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at java.util.Ar

我在内存管理方面遇到了一些问题。我这里有一些代码,它在循环中运行sql查询,将数据放入数组列表,然后进行一些计算。我以前运行过许多类似的程序,但没有这个问题。我将查询放在循环中的原因是,不会在java对象中同时存储太多内存。然而,现在当我运行程序时,每次都会在完全相同的位置(在循环的第29次迭代时)出现内存错误

以下是错误-

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();
            }