【问题标题】:Memory limited image processing in server服务器中内存有限的图像处理
【发布时间】:2011-02-07 13:17:55
【问题描述】:

我们有一个服务器 (Java EE) 应用程序,它将根据用户请求执行一些图像处理工作。如转换图像格式(例如 TIFF 到 JPEG),转换图像颜色(例如 RGB 到 Gray 到 BW),重新采样(resize)图像。一些印刷行业的客户使用非常大的图像,例如 2000 dpi,6 * 8 英寸,4 色组件,需要 6 * 2000 * 8 * 2000 * 4 = 768MB 内存。服务器无法在内存中保存那么大的图像,因此我们决定逐条进行处理。问题是这仍然行不通,因为可能同时有很多客户。您对如何实现内存受限的图像处理有任何想法吗?或者,您知道是否有一些论文/文章可以为我们提供解决方案。

谢谢,

【问题讨论】:

    标签: java c++ c image-processing memory-management


    【解决方案1】:

    我建议考虑将图像处理部分移动到一个单独的 JVM,您可以使用 RMI 或类似方法与您的主应用程序进行通信。

    这允许您将处理 JVM 与主 JVM 分开调整,如果需要,甚至可以在多台机器上创建一个分布式系统。这还可以让您管理转换,以便同时只发生少数转换,从而允许更大的单个图像。

    是否有任何限制可以阻止您这样做?

    作为最后的手段,我建议将实际的图像转换转移到 Linux 上的 ImageMagick 等本地程序,然后由您的程序调用,执行转换,并让您的 JVM 将结果发送给用户。可以说,这在 cpu 方面会更快,并且需要更少的内存。

    【讨论】:

      【解决方案2】:

      您可以使用“平铺”图像处理技术。例如,IPP 支持平铺图像处理。

      【讨论】:

      • 您知道英特尔 IPP 在平铺图像处理方面的最佳实践教程吗?例如,最优化的切片形状是什么(内存连续性的行数,或者在非连续内存中切割图像但在缓存中更小的矩形?)
      【解决方案3】:

      首先您应该知道的是,您可以分配的内存量并不取决于您拥有多少 RAM。操作系统管理虚拟内存,任何分配都在虚拟内存中完成。然后由操作系统将块分页到 RAM/磁盘。你无法控制这一点。您可能认为您在 RAM 中分配了 5 MB,但操作系统将其保留在 RAM 中或在需要时将其从磁盘获取到您的程序。在 Windows 32 位中,您有 2 GB 的用户空间可供使用(其余的由内核空间使用)。在 64 位操作系统中,这个数量要大得多。

      但是,仅仅因为您有 2 GB 的用户空间可以分配(在 32 位操作系统或更多的 64 位操作系统中)并不意味着您总是可以分配这么大的块,因为内存分配需要连续的内存块。所以内存碎片可能会成为一个问题。

      第三件事是 JVM 限制了你可以分配的内存量。所以你需要通过限制堆大小的-Xms -Xmx 参数来增加这些。

      除了这些cmets,我真的没有给你解决方案。

      【讨论】:

      • 是的,我完全理解 VM 机制。我的问题是我们想要一个可以在有限的内存大小(如 64MB)内处理图像的解决方案。简单地扩大内存不是我们的首选。实际上我们所做的只是使用 64 位机器并为 -Xmx 设置非常大的值。但这不适用于 32 位机器。
      • 是的。我认为没有任何简单的解决方案。就像你说的,你可以把它分解成块处理,但时间对其他客户来说变得很重要。您可以查看在 OpenCL(或 CUDA)中实现算法并使用 GPU 阵列从并行处理中获得更快的速度。图像编码之类的事情通常在独立的块中完成,因此这些算法可以很好地扩展。
      猜你喜欢
      • 2010-09-13
      • 2011-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-31
      相关资源
      最近更新 更多