2

私はJavaを使用するのはまったく初めてです。ですから、私の質問は非常に基本的なものになるかもしれません。あらかじめお詫び申し上げます。

多くのコストのかかる反復計算 (主に固有値分解と巨大な行列の乗算) を実行する必要があります。すべての繰り返しは独立しているため、同時に行うことにしました。したがって、これには ExecutorService を使用しています。

私の問題は、-Xms3000m -Xmx3000m を使用してジョブを起動したり、newSingleThreadExecutor() を使用したりしても、スレッドがメモリ不足になることです。メモリ リークが発生したと思いましたが、コードのシリアル バージョンはわずか 80m のヒープ スペースで問題なく動作しました。さらに奇妙なことに (少なくとも私にとっては)、newFixedThreadPool() を使用すると、最初のスレッド (~15) がクラッシュした後、計算が機能し、使用されるヒープが下降し始めます (NetBeans を使用してプロファイリング)。

executor.execute() と executor.submit() も違いなしで試しました。

私が使用しているコードの下に投稿します:

    ExecutorService executor = Executors.newFixedThreadPool(12);       

    double totalMaximumLikelihood = 0.0;
    Iterator iterator1 = myAlignment.columnsMap.keySet().iterator();
    while (iterator1.hasNext()) {
        boolean pairToBeCalculated = false;
        ArrayList<String> myKey1 = (ArrayList) iterator1.next();

        Iterator iterator2 = myAlignment.columnsMap.keySet().iterator();
        while (iterator2.hasNext()) {
            ArrayList myKey2 = (ArrayList) iterator2.next();

            if (pairToBeCalculated == true) {

                Runnable worker = new MySingleCoevolutionRunnable(myKnotsInNewickTree, queryNode, myAlignment, myMeanPosteriorRates, myKey1, myKey2);
                //executor.submit(worker);
                executor.execute(worker);

            } else if (myKey1.equals(myKey2)) {
                pairToBeCalculated = true;
            }
        }

    }
    executor.shutdown();

編集:初心者のエラーを起こしていたようです。スレッドがスケジュールされたとき、ランナブルのコンストラクターは各スレッドのモデルを作成していたため、大量のメモリが必要でした。いくつかのクラッシュの後、残りのスケジュールされたスレッドを実行するのに十分なメモリがありました。

4

0 に答える 0