他们, 我想在Java中使用20000 x 20000或更大的维度创建一个巨大的BufferedImage,但Java会抛出以下异常:
java.lang.OutOfMemoryError:Java堆空间
如何避免此异常? Java是否有可能创建如此大的图像?
答案 0 :(得分:2)
确保使用64位java和64位系统:
在大多数现代32位Windows系统上,最大堆大小范围为1.4G到1.6G。在32位Solaris内核上,地址空间限制为2G。在运行32位VM的64位操作系统上,最大堆大小可能更高,在许多Solaris系统上接近4G。
然后添加一些堆:
尝试-Xmx2048m或-Xmx2g
到你的“java”调用(JVM参数)
因为如果您使用RGB或ARGB类型的图像,那么每个像素都是int
20 000 x 20 000 = 400 000 000 * 4(int有4个字节)= ~400MB * 4 = ~1600 MB
假设您希望拥有更大的图像,并且您的应用程序需要一些空间以及JVM,您可能希望拥有更多或更少的堆,您需要做出决定。
如果您有4GB的RAM,正如您在问题下面的一些评论中所述,这可能会限制您可以创建的图像大小,您需要从4GB减去系统,其他应用程序,JVM的ram数量,那么你就不能创建比你剩下的记忆更大的图像。
答案 1 :(得分:2)
虽然增加堆大小肯定更容易,但我已经创建了一个特殊的DataBuffer
实现,它允许您将BufferedImage
内存保留在堆外。它使用NIO内存映射文件缓冲区,其工作方式类似于虚拟内存。它比使用普通BufferedImage
慢,但可能会帮助您加载和处理原本太大的图像。
有关实施的信息,请参阅MappedImageFactory.java和MappedFileBuffer.java(获得BSD许可)。
用法很简单:
int w = 20000;
int h = 20000;
BufferedImage image = MappedImageFactory
.createCompatibleMappedImage(w, h, BufferedImage.TYPE_INT_ARGB);
我已成功使用它来加载和显示一个只有32 MB堆的2 GB图像。
答案 2 :(得分:0)
您可以像这样创建黑白图像(1位/像素):
IndexColorModel colorModel = new IndexColorModel(
1, // bits per pixel
2, // number of colors
new byte[]{0, (byte) 0xff}, // red values
new byte[]{0, (byte) 0xff}, // green values
new byte[]{0, (byte) 0xff}); // blue values
BufferedImage image = new BufferedImage(20000, 20000,
BufferedImage.TYPE_BYTE_BINARY, colorModel);
需要20000 * 20000位= 50 MB。