用Java创建一个巨大的BufferedImage

时间:2017-01-20 12:41:52

标签: java bufferedimage

他们, 我想在Java中使用20000 x 20000或更大的维度创建一个巨大的BufferedImage,但Java会抛出以下异常:

  

java.lang.OutOfMemoryError:Java堆空间

如何避免此异常? Java是否有可能创建如此大的图像?

3 个答案:

答案 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.javaMappedFileBuffer.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。