This is more of a generic question which has to do with static variables and the process life cycle.
I have developed a heavy multi threaded signal processing Android app. It is targeted at API level 9 and above, and if I can it will restricted to only dual core devices. This is purely an academic App and not intended for the general user, and has been developed for teaching Digital Signal Processing. So for this reason I am calculating the DFT many times and so forth so there is quite a bit of computation and size allocation required.
I have declared a bunch of static float and double arrays which get used in static functions like in the example below. The complete code is is a bit to big to put here, so the example below just illustrates the idea.
public class SpecMod {
//Example of global static declarations
static double [][] spectrum = null;
static double [][] phaseMat = null;
static float [][] mframes = null;
static float [][] sframes = null;
static double [] mag = null;
static double [] Pxx = null;
static double [] GAMk = null;
static int nfft = 512;
static float nsegs = 560;
//Compute FFT data
public static void calcSpec(int fs, float [] buffer, float f, float g){
//Example of static array memory allocation
sframes = new float[nlen][(int) nsegs];
spectrum = new double[nfft][(int) nsegs];
phaseMat = new double[nfft][(int) nsegs];
mframes = new float[nlen][(int) nsegs];
mag = new double[nfft];
Pxx = new double[nfft];
GAMk = new double[nfft];
}
public static void fillArrays(){
//Example of array manipulation
for (int j = 0; j < nsegs; j++) {
for (int i = 0; i < nfft; i++) {
mag[i] = spectrum[i][j];
phase[i] = phaseMat[i][j];
Pxx[i] = Math.pow(Math.abs(mag[i]), 2);
GAMk[i] = (Pxx[i] / muPnn[i]);
}
}
}
}
The application is working great as it is. The problem lies in different execution times when say the function fillArrays() gets called. The first time the function is called it takes only 4 seconds to complete, however the second and each subsequent time it is run it takes closer to 30 seconds to complete. In log cat you can see that the heap size does increase drastically the second time, but every subsequent time it stays about the same. In MAT the two dimensional array 'spectrum' retains a large portion of heap. This is understandable as it would contain nfft*nsegs (512*560) sized data stored as doubles.
So I am not sure if the time taken is due to the Garbage collector or perhaps the interpreter going into each step of the for loops (strange tho if the first execution is still short). I thought maybe for all other arrays, setting them to non-static weakreferences so the garbage collector can clean them up, but it seems everything I try is to the same time effects. So the question is, when using large array objects what is the most effective way to allocate space for them. At the moment they are static, but are not final as the size changes frequently due to user preference. Any help would be great thanks.
- Note this is just example code, calcSpec() gets called each time the user changes parameters or a new audio file is loaded to compute frequency data 'spectrum', then only after calcSpec is called, the user can call fillArrays(). In terms of profiling, I have been using MemoryAnalyzer and allocation tracker. The odd thing here the time increase is only in fillArrays(). The first execution it take 4seconds, the second (without calling calcSpec() again, so the same spectrum data is used again) it takes 30 seconds. In both Mat and allocation tracker the Retained size and allocation size are the same for every execution.