简体   繁体   English

图像和数组存储中的“java.lang.OutOfMemoryError:Java堆空间”

[英]“java.lang.OutOfMemoryError: Java heap space” in image and array storage

I am currently working on an image processing demonstration in java (Applet). 我目前正在java(Applet)中进行图像处理演示。

I am running into the problem where my arrays are too large and I am getting the "java.lang.OutOfMemoryError: Java heap space" error. 我遇到了我的数组太大而我得到“java.lang.OutOfMemoryError:Java堆空间”错误的问题。

The algorithm I run creates an NxD float array where: N is the number of pixel in the image and D is the coordinates of each pixel plus the colorspace components of each pixel (usually 1 for grayscale or 3 for RGB). 我运行的算法创建一个NxD浮点数组,其中:N是图像中像素的数量,D是每个像素的坐标加上每个像素的颜色空间分量(通常1表示灰度,3表示RGB)。 For each iteration of the algorithm it creates one of these NxD float arrays and stores it for later use in a vector, so that the user of the applet may look at the individual steps. 对于算法的每次迭代,它创建这些NxD浮点数组中的一个并存储它以供稍后在向量中使用,以便applet的用户可以查看各个步骤。

My client wants the program to be able to load a 500x500 RGB image and run as the upper bound. 我的客户希望程序能够加载500x500 RGB图像并作为上限运行。 There are about 12 to 20 iterations per run so that means I need to be able to store a 12x500x500x5 float in some fashion. 每次运行大约有12到20次迭代,这意味着我需要能够以某种方式存储12x500x500x5浮点数。

Is there a way to process all of this data and, if possible, how? 有没有办法处理所有这些数据,如果可能的话,如何处理?

Example of the issue: I am loading a 512 by 512 Grayscale image and even before the first iteration completes I run out of heap space. 问题示例:我正在加载512 x 512灰度图像,甚至在第一次迭代完成之前,我的堆空间用完了。 The line it points me to is: 它指出的路线是:

Y.add(new float[N][D]) Y.add(新浮[N] [D])

where Y is a Vector and N and D are described as above. 其中Y是Vector,N和D如上所述。 This is the second instance of the code using that line. 这是使用该行的代码的第二个实例。

EDIT: The upper bound, as I mentioned but forgot to correct should be around: 20+ x500x500x5 (20 iterations, 500 width, 500 height, 5 dimensions (where 3 comes from RGB and 2 for the coordinates (The coordinates move and so do the pixels, so I need to record the values, which can and are decimals)) (Approx. 100000000 bytes) 编辑:上限,正如我提到但忘记纠正应该是:20+ x500x500x5(20次迭代,500宽度,500高度,5维度(其中3来自RGB,2来自坐标(坐标移动等等)像素,所以我需要记录值,这可以是小数))(约100000000字节)

I don't think you are going to be able to do this as an Applet. 我不认为你能够像Applet一样做到这一点。 (There may be settings in the browser for how much memory to assign to applets, but I'm not aware of any.) (浏览器中可能存在分配给applet的内存量的设置,但我不知道。)

If you can use Java webstart, I would use that. 如果您可以使用Java webstart,我会使用它。 You can set the amount of memory required: 您可以设置所需的内存量:

<j2se version="1.4+" initial-heap-size="100M" max-heap-size="200M"/>

The advantage with using webstart is that the user does not need to configure their browser. 使用webstart的优点是用户不需要配置他们的浏览器。

EDIT: The Java control panel does have memory settings for applets. 编辑:Java控制面板确实有applet的内存设置。 See How can I start an Java applet with more memory? 请参阅如何启动具有更多内存的Java小程序?

However, unless you have just a handful of clients who don't mind altering their java settings (and that they have appropriate permissions and skills), this is not a nice user experience. 但是,除非你只有少数客户不介意改变他们的java设置(并且他们有适当的权限和技能),否则这不是一个很好的用户体验。 With web start,you can set all this up in the JNLP descriptor and you're all set to go. 通过Web启动,您可以在JNLP描述符中设置所有这些,并且您已准备就绪。

Have you tried increasing the initial heap size, as well as setting the maximum heap size? 您是否尝试过增加初始堆大小以及设置最大堆大小?

java -Xms<initial heap size> -Xmx<maximum heap size>

eg 例如

java -Xms256M -Xmx512M

The defaults are pretty conservative, and small so you definitely want to try and play around with your heap size settings. 默认值非常保守,而且很小,所以你肯定想尝试使用堆大小设置。

1) 12x500x500x5 floats means about 60 MB, plus some overhead. 1)12x500x500x5浮动意味着大约60 MB,加上一些开销。 You should have no problem reserving all that memory space on a reasonable machine, if you configure your JVM heap correctly (-Xmx500M for example). 如果正确配置JVM堆(例如-Xmx500M),则在合理的计算机上保留所有内存空间应该没有问题。 If on the other hand you run this as an applet, you should do some settings (I found this link for example, relevant for Java 6 update 10 and above). 另一方面,如果你将它作为applet运行,你应该做一些设置(我发现这个链接,例如,与Java 6更新10及更高版本相关)。

2) You didn't provide much information regarding the data format per pixel. 2)您没有提供有关每像素数据格式的大量信息。 Maybe you can make it more compact. 也许你可以让它更紧凑。 Why do you need 5 floats per pixel? 为什么每个像素需要5个浮点数? You can store an RGB value as 3 bytes, and it seems you don't need to store the pixel location, since the position in the 2dimensional array already indicates the position. 您可以将RGB值存储为3个字节,并且您似乎不需要存储像素位置,因为2维数组中的位置已经指示了位置。

To increase the heap space size beyond the default 64MB, you need to execute the application with -Xmx parameter (for the applet add it in the Java Runtime Settings which you can find in the administration tools on any OS). 要将堆空间大小增加到超过默认的64MB,您需要使用-Xmx参数执行应用程序(对于applet,将其添加到Java Runtime Settings中,您可以在任何操作系统的管理工具中找到它)。 I guess though it's not an option in case this is gonna be a web application where you'll have to modify a lot of end-user machines. 我想虽然这不是一个选项,如果这将是一个Web应用程序,你将不得不修改许多最终用户的机器。 I'd like to find out more about that storage in an x-dimensional array. 我想在x维数组中找到更多关于该存储的信息。 What exactly do you store? 你到底存的是什么? Why 4-byte floats? 为什么4字节浮点数? The uncompressed raw image is usually stored in an WIDTHxHEIGHT array where each cell contains a color object (eg 3 shorts describing RGB space). 未压缩的原始图像通常存储在WIDTHxHEIGHT阵列中,其中每个单元格包含颜色对象(例如,3个描述RGB空间的短路)。 Such an array for a 500x500 image would require 500 * 500 * 3 (the amount of color dimensions) * 2(bytes for a short) = 1 500 000 bytes, way less than 500 * 500 * 5 (still haven't figured out why 5, probably you store color + coordinates) * 4 (bytes in float) = 5 000 000 bytes. 500x500图像的这种阵列需要500 * 500 * 3(颜色尺寸的数量)* 2(短的字节)= 1 500 000字节,小于500 * 500 * 5的方式(仍然没有弄清楚)为什么5,可能你存储颜色+坐标)* 4(浮点数字节)= 5 000 000字节。 Have in mind that exactly for this reason compression algorithms (like JPEG) have been developed, so that you don't have to keep in memory 1.5MB for each image. 请记住,正是由于这个原因,开发了压缩算法(如JPEG),因此您不必为每个图像保留1.5MB的内存。 As of the iterations, but mostly for consequent storage of those, there's not much to say, unless you want to get into the hassle to write something like MPEG format where you'll have to only save the changes between frames. 从迭代开始,但主要是为了后续存储,没有什么可说的,除非你想要编写类似MPEG格式的东西,你必须只保存帧之间的变化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM