我目前正在使用java(Applet)进行图像处理演示。
我遇到的问题是我的数组太大而且我收到了“java.lang.OutOfMemoryError:Java堆空间”错误。
我运行的算法创建一个NxD浮点数组,其中:N是图像中像素的数量,D是每个像素的坐标加上每个像素的颜色空间分量(通常1表示灰度,3表示RGB)。对于算法的每次迭代,它会创建其中一个NxD浮点数组并存储它以供以后在向量中使用,以便applet的用户可以查看各个步骤。
我的客户希望程序能够加载500x500 RGB图像并以上限运行。每次运行大约有12到20次迭代,这意味着我需要能够以某种方式存储12x500x500x5浮点数。
有没有办法处理所有这些数据,如果可能的话,有哪些方法?
问题示例:我正在加载512 x 512灰度图像,甚至在第一次迭代完成之前,我的堆空间用完了。它指出的路线是:
Y.add(新浮[N] [D])
其中Y是Vector,N和D如上所述。这是使用该行的代码的第二个实例。
编辑:上限,正如我所提到但忘记纠正应该是:20+ x500x500x5(20次迭代,500次宽度,500次高度,5次维度(其中3来自RGB,2来自坐标(坐标移动)像素一样,所以我需要记录值,这些值可以是小数))(约100000000字节)答案 0 :(得分:3)
我认为你不能像Applet一样做到这一点。 (浏览器中可能会设置分配给applet的内存量,但我不知道。)
如果您可以使用Java webstart,我会使用它。您可以设置所需的内存量:
<j2se version="1.4+" initial-heap-size="100M" max-heap-size="200M"/>
使用webstart的优势在于用户无需配置浏览器。
编辑:Java控制面板确实有applet的内存设置。看到 How can I start an Java applet with more memory?
但是,除非你只有少数客户不介意改变他们的java设置(并且他们有适当的权限和技能),否则这不是一个很好的用户体验。通过Web启动,您可以在JNLP描述符中设置所有这些,并且您已准备就绪。
答案 1 :(得分:-1)
您是否尝试过增加初始堆大小,以及设置最大堆大小?
java -Xms<initial heap size> -Xmx<maximum heap size>
e.g。
java -Xms256M -Xmx512M
默认值非常保守,而且很小,所以你肯定想尝试使用堆大小设置。
答案 2 :(得分:-1)
1)12x500x500x5浮点数意味着大约60 MB,加上一些开销。如果正确配置JVM堆(例如-Xmx500M),则在合理的计算机上保留所有内存空间应该没有问题。另一方面,如果您将其作为applet运行,则应该进行一些设置(我发现this链接,例如,与Java 6 update 10及更高版本相关)。
2)您没有提供有关每像素数据格式的大量信息。也许你可以让它更紧凑。为什么每个像素需要5个浮点数?您可以将RGB值存储为3个字节,并且您似乎不需要存储像素位置,因为2维数组中的位置已经指示了位置。
答案 3 :(得分:-1)
要将堆空间大小增加到超过默认的64MB,您需要使用-Xmx参数执行应用程序(对于applet,将其添加到Java Runtime Settings中,您可以在任何操作系统的管理工具中找到它)。我想虽然这不是一个选项,如果这将是一个Web应用程序,你将不得不修改许多最终用户的机器。 我想在x维数组中找到更多关于该存储的信息。你到底存的是什么?为什么4字节浮点数?未压缩的原始图像通常存储在WIDTHxHEIGHT阵列中,其中每个单元包含颜色对象(例如,描述RGB空间的3个短路)。 500x500图像的这种阵列需要500 * 500 * 3(颜色尺寸的数量)* 2(短的字节)= 1 500 000字节,小于500 * 500 * 5的方式(仍然没有弄清楚)为什么5,可能你存储颜色+坐标)* 4(浮点数字节)= 5 000 000字节。 请记住,正是由于这个原因,开发了压缩算法(如JPEG),因此您不必为每个图像保留1.5MB的内存。 从迭代开始,但主要是为了后续存储,没有什么可说的,除非你想要编写类似MPEG格式的东西,你只需要在帧之间保存更改。