我一直与我的项目的同时,其在某些点计算大图像的直方图(高达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