2

I have this piece of code in android, which is causing massive logs of 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);
    }

below are few of the logs

    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

thanks in advance

Ahsan Zaheer
  • 646
  • 1
  • 12
  • 18
  • You create `4096^2` objects - are you really using all of them ? don't forget that you're using a phone with limited amount of memory! – Nir Alfasi Feb 06 '14 at 06:52
  • So what is your actual question? So far, the only possible answer is *"Yes - that is expected behaviour for code like that"*. – Stephen C Feb 06 '14 at 07:38
  • When i commented out the line "results[times] = FFT.fft(complex);" The GC logs stopped. Is FFT of a complex number a very heavy operation? – Ahsan Zaheer Feb 06 '14 at 07:47
  • I do have similar problem with this exact gc when i am performing loop in my program, have you found the solution yet? – Rijdzuan Sampoerna Feb 10 '14 at 13:43
  • Nopes, What i'm beginning to think that performing FFT on a complex number in an Android phone is a heavy operation, and would take up a lot of its memory. – Ahsan Zaheer Feb 12 '14 at 04:57

1 Answers1

0

Your problem is that in Java, a Complex is a heap-allocated Java object. I believe that it is immutable, so new Complex instances must be made for each and every calculation. This makes working math on complex numbers extremely slow and allocate a large amount of memory. It thus should be avoided whenever possible.

The only solution in pure Java is to not use the built-in Complex type, and instead do the FFT directly on pairs of double arrays, one each for the real and imaginary parts. Alternatively, one can use a single array containing both the real and imaginary parts, though the comments to this question imply that the first approach tends to give better performance. The lack of non-heap-allocated objects is an unfortunate limitation of the JVM.

For even higher performance, the best approach is to use a native library. One option is FFTS, which is BSD licensed and comes with JNI bindings. It uses run-time code generation and SIMD instructions to achieve performance far higher than any pure-Java library can.

Demi
  • 3,535
  • 5
  • 29
  • 45