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