【发布时间】:2013-11-07 19:58:34
【问题描述】:
我有 Java 应用程序,它集中处理 2D 浮点数组(float[][] 数组),它实际上将图像保存在黑色背景上。两个维度都等于(正方形)并且是 2 的幂(大多数是 256、512、1024),因此在大多数情况下,靠近边界的区域为零。
为了提高性能(存在一些 FFT)和降低对这些数组的操作(如旋转等)的复杂性,将大小设置为 2 的幂。 最近,我在 6Gb 的机器上遇到了这个应用程序的堆不足问题。 根据我的计算 - 此应用程序的内存消耗应该高达 2-3Gb,而它达到 4-5Gb(在 Windows 任务管理器中查看)。 我使用了“YourKit”分析器,它表明这些浮点数组确实占用了大部分内存,但是,这些浮点数组的总粗略大小应该是 1.3Gb(嗯,我知道由 JVM 来决定如何存储数据,但是我没想到内存消耗会相差 2-3 倍)。
我尝试使用 Snappy 压缩器即时压缩/解压缩数据(内存消耗降至 3.5Gb),但性能下降了好几次,这不是很可接受。 另外,我在用 BufferedImage 替换那些 floats[][] 时测试了性能,但性能很差。
所以,我还有 2 种方法可以减少内存消耗: 1) 为 float[][] 数组编写包装器以保存“零”元素(有很多“空”行和列) 2)远离“2的幂”
这两种方式都需要大量的编码/重构,所以当我在思考“成为或不成为”时,你们对这个问题可能有更好的线索吗?
谢谢!
【问题讨论】:
-
floats 代表什么?例如,您为什么不能将它们设为ints? -
我会更加注意数组的使用方式,以及是否引入了任何临时数组,这将显着提高内存使用率。您可能还想研究一些用于稀疏数组的 Java 类。
-
@Arsen 你如何将 RGB 图像存储在 float[][] 中,我不禁相信你有颜色通道的第三维。向我们展示这样一个数组的实际声明,并评论像素是如何存储在其中的。
-
@Arsen 那么你的数组 是 三维的吗?这很容易解释意外的内存消耗(java多维数组被实现为数组数组)。由于每个数组都有一些开销(大约 12 个字节),对于最里面的 float[3] 而言,这相当于存储在其中的浮点数所消耗的内存。无论如何,这就是您的代码示例所暗示的。我特别询问了这种数组的实际声明,因为这会明确地清除您真正使用的内存布局。玩猜谜游戏对任何人都没有帮助。使用所有相关详细信息更新您的问题
-
@Arsen Hotlicks 和我对你的解释也有问题:你展示的代码创建了一个每个像素 3 个浮点数 的数组。您告诉我们数组是由 (x, y) 索引的二维数组。这根本不适合,同意吗?然后你说每个像素一个浮点数,在这种情况下,它更没有意义,因为热点指出了精度问题。然后你说你需要一个用于 FFT 的浮点数,但是将 R、G 和 B 放在一起的浮点数几乎不适合 FFT 处理(除了精度问题),因为你需要拆分颜色通道 无论如何在处理之前。尽量减少混乱/困惑
标签: java arrays out-of-memory fft memory-optimization