私のプロジェクトでは、ある時点で大きな画像のヒストグラムを計算しています(最大40Mpxの写真で作業しますが、一般的に約10-20Mpxです)。"outOfMemoryError java heap space"ヒストグラムの計算、RAMとTimeの取引?
私は常に私はヒストグラムを計算していたときにこの例外が現れ始めました。
私はこの計算方法に切り替えましたなぜなら、すべてのピクセルに対して繰り返し処理を行い、各ピクセルのすべての色を取得するよりも高速だったからです。
コード?
私がプログラムを高速化しようと思えば、私はもっと多くのRAM(この大きなdouble []オブジェクト)を使う必要があると思います。 PCに十分なRAMがある場合、問題はなく、プログラムはスムーズに実行されますが、PCにこのようなRAMがないと、クラッシュしてプログラムが役に立たなくなります。
すべてのピクセルを手作業で反復処理してコードを「より遅く」書き、「安全」にする必要がありますか?
私は間違ったことをしていますか、どちらも同時に行うことができますか?
// dataset
dataset = new HistogramDataset();
final int w = image.getWidth();
final int h = image.getHeight();
double[] r = new double[w * h]; //Here some PC's with not enough RAM will crash
double[] s = new double[w * h];
double[] t;
r = raster.getSamples(0, 0, w, h, 0, r);
s = r;
dataset.addSeries(lang.getString("HistogramRGB.String.red"), r, BINS);
r = raster.getSamples(0, 0, w, h, 1, r);
t = new double[r.length + s.length]; //Add R+G
System.arraycopy(s, 0, t, 0, s.length);
System.arraycopy(r, 0, t, s.length, r.length);
dataset.addSeries(lang.getString("HistogramRGB.String.green"), r, BINS);
r = raster.getSamples(0, 0, w, h, 2, r);
s = new double[r.length + t.length]; //Add R+G+B
System.arraycopy(t, 0, s, 0, t.length);
System.arraycopy(r, 0, s, t.length, r.length);
dataset.addSeries(lang.getString("HistogramRGB.String.blue"), r, BINS);
dataset.addSeries(lang.getString("HistogramRGB.String.brigthness"), s, BINS);
// chart
chart = ChartFactory.createHistogram(lang.getString("HistogramRGB.String.histogram"), "",
"", dataset, PlotOrientation.VERTICAL, false, true, false);
更新: を-Xmxはコメントで提案オプションを使用しても問題が解決し
これはこれはOutOfMemoryErrorが発生したコードの一部です。少ないと最適化の後に例外
- :窓10 32ビットと3,5GBラムを使用して、仮想マシンで、@TheConstructorの最適化を使用して
結果
:-Xmx824mは例外java -XX:+PrintFlagsFinal -version | findstr HeapSize uintx ErgoHeapSizeLimit = 0 {product} uintx HeapSizePerGCThread = 67108864 {product} uintx InitialHeapSize := 16777216 {product} uintx LargePageHeapSizeThreshold = 134217728 {product} uintx MaxHeapSize := 268435456 {product} java version "1.8.0_111" Java(TM) SE Runtime Environment (build 1.8.0_111-b14) Java HotSpot(TM) Client VM (build 25.111-b14, mixed mode, sharing)
を実行するよりも、これは私がデフォルトで持っているものです
これは約268MBで、このコンピュータのコマンドで設定できる最大値は1,5GBです。他のプログラムを使ってウィンドウ全体を開くことなく、3.5GBの2GBが必要なことは奇妙なことです。
あなたのプログラムで使用されているメモリを増やしても、アルゴリズムの最適化は解決されません。これを実行するには、-Xms1024mを試してみてください(あなたのJDKが許すRAMの量を確認しなければなりません。一般的には、サーバまたはクライアントのバージョンによって異なります)。-XX:MaxPermSize = 128m。ここでは、パラメータの説明です:https://blog4jose.wordpress.com/2009/02/02/memory-permgen-classloader/ – sirandy
'-Xmx' JVMオプションを指定しましたか?そうでない場合は、まずそれを試してください。 – Andreas