【问题标题】:Image in memory consuming much more memory than its file size内存中的图像消耗的内存比其文件大小多得多
【发布时间】:2023-03-30 00:15:01
【问题描述】:

我正在使用 Java (Eclipse) 构建一个处理照片的应用程序。

所以我使用此链接Java get available memory 来了解我还有多少可用内存。问题是我有这个代码:

Main.printMemory("before image");
url = new File(information.getPath()).toURI().toURL();
image = ImageIO.read(url);
Main.printMemory("after image");

结果是:

消息:图像前
可用内存(字节):82554768
最大内存(字节):129957888
总内存(字节): 85000192

消息:图像后
可用内存(字节):42600680
最大值 内存(字节):129957888
总内存(字节):85000192

所以加载该图像需要82554768 - 42600680 = 39954088 bytes = 38 MB

照片大小为 3.3 MB

占用这么多内存正常吗???为什么会消耗这么多内存?有什么办法可以减少这种情况,希望能保持照片质量?

【问题讨论】:

  • 图片有多大,以像素为单位?
  • 4000 × 3000及其JPEG图像
  • 4000 x 3000 x 3 字节/像素 = 36000000 字节。 (图像不会压缩存储在内存中)
  • 我刚刚加载了 5 张照片,大约 2-4MB 和可用内存
  • 振荡 82554872 到 42839376 到 31523760 到 54946760 到 43621704 到 6062136 到 18054976

标签: java image memory memory-management


【解决方案1】:

压缩和编码图像的文件大小是存储图像的内存要求的不良指标。主存中的图像通常是未压缩的,因为使用压缩编码会使图像操作更加复杂且速度慢很多。

您有一个4,000 x 3,000 JPEG 图像。由于源是 JPEG 编码的,它可能由ImageIOTYPE_INT_RGB 加载,这意味着每个像素都需要4 字节(int)的存储空间。这意味着解码后的图像将使用最多需要4,000 x 3,000 x 4 = 48,000,000 字节的内存。当 Java 支持 16 位颜色深度时,这个数字甚至可能更大。

它只需要 ~ 38MB 听起来好像图像没有完全解压缩 (TYPE_INT_RGB),但实际上在主内存中以一些压缩编码表示(例如 TYPE_3BYTE_BGR 需要 36 MB)。

图片很大。

【讨论】:

    【解决方案2】:

    这很正常,是的。原因是大多数图像格式都以某种方式压缩——例如 gif、jpeg 和 png 都是如此——但 BufferedReader 不是。也就是说,它独立记录每个像素的数据,而不试图压缩或整合这些信息。这会产生更大的内存占用:宽度 x 高度 x(每像素字节数)。如果最后一个是 4 字节,您可以看到图片如何很快变得相当大。

    如果您想处理图像,您无能为力——旋转它们、过滤它们等等。这就是为什么照片编辑工具一直是内存猪的原因!如果您不需要完整分辨率,可以使用 imgscalr 或其他库之类的方式对图像进行下采样。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-15
      • 2021-05-13
      相关资源
      最近更新 更多