我一直與我的項目的同時,其在某些點計算大圖像的直方圖(高達40Mpx,但一般圍繞10-20Mpx照片的工作。我總是用「outOfMemoryError java堆空間」計算直方圖,內存與時間的交易?
筆記本電腦與16GB的RAM,我沒有注意到任何問題今天我切換到一個6GB的內存筆記本電腦,並與17Mpx的照片這個例外開始出現時,我正在計算一個直方圖
我已經切換到這種計算方式這是因爲它比遍歷所有像素並獲得每個像素中的所有顏色更快。
你對如何編寫這樣的建議有什麼建議?一個代碼?
如果我想讓程序更快,我想我需要使用更多的RAM(這個大的double []對象)。如果電腦有足夠的內存不會有任何問題,程序將運行平穩,但如果電腦沒有這麼多的RAM,它只會崩潰,並使程序無用。
因此,我應該用「手動」遍歷所有像素並使其「更安全」以「較慢的方式」編寫代碼?
或者我做錯了什麼,這兩件事情可以在同一時間完成?
這是一段代碼是這樣的OutOfMemoryError發生:
// 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在評論中建議的選項解決問題。
結果使用Windows 10 32位和3,5GB RAM使用@TheConstructor優化,在虛擬機:
- 小於-Xmx1444m將運行異常
- 用更少的優化後優化前比-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。我發現奇怪的是,沒有其他任何程序打開整個Windows與任何其他程序需要2GB的3.5GB。
一個快速的回答是:增加你的程序使用的內存,但它不解決您的算法優化。爲了運行這個,你可以試試:-Xms1024m(你必須檢查你的JDK允許多少RAM,通常取決於服務器或客戶端版本),後面跟-XX:MaxPermSize = 128m。這裏你是對參數的解釋:https://blog4jose.wordpress.com/2009/02/02/memory-permgen-classloader/ – sirandy
你是否指定了'-Xmx' JVM選項?如果不是,請先嚐試一下。 – Andreas