我在android中有这段代码,导致GC的大量日志
// When turning into frequency domain we'll need complex numbers:
byte audio[] = out.toByteArray(); //approx size 827392
int amountPossible = 200;
Complex[][] results = new Complex[amountPossible][];
// For all the chunks:
for (int times = 0; times < amountPossible; times++) {
Complex[] complex = new Complex[4096];
for (int i = 0; i < 4096; i++) {
// Put the time domain data into a complex number with imaginary
// part as 0:
complex[i] = new Complex(audio[(times * 4096) + i], 0);
}
// Perform FFT analysis on the chunk:
results[times] = FFT.fft(complex);
}
以下是几个日志
D/dalvikvm(10602): GC_CONCURRENT freed 805K, 88% free 3911K/31075K, paused 2ms+5ms
D/dalvikvm(10602): GC_CONCURRENT freed 1796K, 88% free 3957K/31075K, paused 1ms+2ms
D/dalvikvm(10602): GC_CONCURRENT freed 1811K, 88% free 3970K/31075K, paused 1ms+3ms
D/dalvikvm(10602): GC_CONCURRENT freed 1711K, 87% free 4102K/31075K, paused 2ms+3ms
D/dalvikvm(10602): GC_CONCURRENT freed 1806K, 87% free 4138K/31075K, paused 1ms+3ms
D/dalvikvm(10602): GC_CONCURRENT freed 1755K, 87% free 4226K/31075K, paused 1ms+3ms
D/dalvikvm(10602): GC_CONCURRENT freed 1827K, 87% free 4242K/31075K, paused 1ms+3ms
D/dalvikvm(10602): GC_CONCURRENT freed 1732K, 87% free 4258K/31075K, paused 2ms+2ms
D/dalvikvm(10602): GC_CONCURRENT freed 1714K, 86% free 4387K/31075K, paused 1ms+3ms
提前致谢
答案 0 :(得分:0)
您的问题是,在Java中,Complex
是堆分配的Java对象。我相信它是不可变的,因此必须为每个计算创建新的Complex
个实例。这使得复数上的数学运算非常慢并且分配了大量内存。因此应尽可能避免这种情况。
纯Java中唯一的解决方案是不使用内置的Complex
类型,而是直接在成对的double
数组上进行FFT,每个数组分别用于实部和虚部。或者,可以使用包含实部和虚部的单个数组,但this question的注释意味着第一种方法倾向于提供更好的性能。缺少非堆分配的对象是JVM的一个不幸的限制。
为了获得更高的性能,最好的方法是使用本机库。一个选项是FFTS,它是BSD许可的,并带有JNI绑定。它使用运行时代码生成和SIMD指令来实现远高于任何纯Java库的性能。