Ars*_*sen 5 java arrays fft out-of-memory memory-optimization
我有Java应用程序,它集中使用2D浮点数组(float [] []数组),实际上在黑色背景上保存图像.两个维度都是等于(正方形)并且是2的幂(大多数是256,512,1024),因此在大多数情况下,靠近边界的区域具有零.
大小等于2的功率以提高性能(存在一些FFT)并且降低了那些阵列上的操作的复杂性,例如旋转等.最近我在6Gb的机器上面临这个应用程序的堆缺乏.通过我的计算 - 这个应用程序的内存消耗应该高达2-3Gb,而它达到4-5Gb(在Windows任务管理器中查看).我使用了"YourKit"分析器,它显示那些浮点数阵列确实占用了大部分内存,但是,这些浮点数组的总粗略大小应该是1.3Gb(嗯,我知道由JVM决定如何存储数据,但是我没想到内存消耗会有2-3倍的差异.
我试图使用Snappy压缩器动态压缩/解压缩数据(并且内存消耗降至3.5Gb),但性能下降了几次,这是不可接受的.此外,我在BufferedImage替换那些浮动[] []时测试性能,但性能非常差.
因此,还有两种方法可以减少内存消耗:1)为float [] []数组写包装器以保存"零"元素(有很多"空"行和列)2 )远离"2的力量"
这两种方式都需要相当多的编码/重构,所以当我想"成为或不成为"时 - 你可能对这个问题有更好的线索,伙计们?
谢谢!
FFT 需要一个复数数组,该数组的大小是实际数据数组的两倍,即使您在输入处从实数组转换并在最后转换回幅度数组也是如此。这可能导致内存使用量比预期大 2 倍。
稀疏数组不适用于 FFT,因为 FFT 中的中间步骤几乎总是填充整个复数数组。
许多现代高性能 FFT 库(例如基于 FFTW 的库)可以非常有效地处理除 2 的幂之外的 FFT 长度(任何小素数乘积的长度都可以非常有效地进行 FFT)。这可以为多种尺寸节省大量 2D 填充。