2

メモリ管理でいくつかの問題に直面しています。ここには、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();
}
4

2 に答える 2

2

ここにいくつかのパフォーマンスの問題があります:

  1. SQL はパラメーター化されていないため、データベースは毎回クエリを再コンパイルする必要があります。準備済みステートメントの使用を検討してください。
  2. ネストされたループ。ネストされたループが 4 つあるポイントが 1 つあります。
  3. 変数名と過度のループのために、ロジックが何をしているのかを理解する方法はありません。それが可能で、それがロジックにあるかどうかわからない場合 (実行している集計によって異なります)、while (rs.next()) ループで一度に 1 つのオブジェクトをすべて実行できますか?

元:

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
}
于 2013-05-17T23:53:53.843 に答える
0

これが機能したコードのバージョンです(私自身の参照用)。

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();
        }
于 2013-05-18T03:05:09.880 に答える