garbage collection - Android - Heap usage at Application Start and CG_CONCURRENT -


i'm having troubles performances on application because of gc, , don't have experience understand what's going on. here's detailed situation of what's happening.

i'm trying build application processes audio in real time applying stft (quick explanation).

basically, take each buffer (in case, min buffer size 1148 bytes), apply windowing function , obtain matrix of frames; on each frame apply fft; finally, can apply each frame gain based on frequency , on moment in time. path in order obtain modified version of buffer.

since sampling frequency 8000hz, have each buffer processing in less 1148/8000 = 144ms. using system.currenttimemillis() evaluated each buffer processing takes between 70 , 100 ms, that's fine.

but problem comes garbage collector: memory seems full, can see screenshot below; , gc action makes audio crack sometimes.

log of application

the problem i've noticed 2 things:

  • if don't fft , ifft, leave frame is, cg_concurrent message doesn't display. that's because fft produces lot of data (arrays of complex numbers)

  • all operations done in separate thread; i've tried cause manually cg ddms perspective after application has been launched. can see code below, in oncreate method application loads layout.. when cause cg, see heap more 90% used ! i've looked @ heap dump , generated leaks suspect report, , of memory occupied class 'android.content.res.resources' , 'android.graphics.bitmap'.. (here's screenshots)

heap usage after application start

leaks report piechart

so, have suggestions ? think that's strange memory 90% used @ beginning.. , heap can not increase bit in order satisfy needs

code

mainactivity.java

package com.example.fileoutjava;  import java.io.datainputstream; import java.io.ioexception; import java.io.inputstream;  import android.app.activity; import android.media.audioformat; import android.media.audiomanager; import android.media.audiotrack; import android.os.bundle; import android.util.log; import android.view.menu; import android.view.view;  public class mainactivity extends activity {      static final int buffer_factor = 1;       datainputstream dis;     static final int freq = 8000;     static final int frame_lenght = 32;     static final int frame_shift = 16;     boolean ismusicstopped = true;     audiotrack at;     thread playthread;     long time;       @override     protected void oncreate(bundle savedinstancestate) {         super.oncreate(savedinstancestate);         setcontentview(r.layout.activity_main);      }       public void playmusic(view v) {         if (at == null) {             log.d("play music", "launching new player");             playthread = new thread(musicplayerthread);             playthread.start();         }         }      public void stopmusic(view v) {         ismusicstopped = true;         playthread = null;     }       runnable musicplayerthread = new runnable() {                public void run() {             thread.currentthread().setpriority(thread.max_priority);              /* eg: 8000 bytes per second, 1000 bytes = 125 ms */              inputstream = null;             datainputstream dis = null;              try {                 = mainactivity.this.getapplicationcontext().getassets().open("test.wav");             } catch (ioexception e) {                 e.printstacktrace();             }             if (is!=null)                 dis = new datainputstream(is); //dis = new datainputstream(new bufferedinputstream(is,bsize));              ismusicstopped = false;              int min_bsize = audiotrack.getminbuffersize(freq, audioformat.channel_out_mono, audioformat.encoding_pcm_16bit);             int bsize = min_bsize*buffer_factor;              stft stft = new stft(frame_shift,frame_lenght,freq,bsize);              @ = new audiotrack(audiomanager.stream_music, freq, audioformat.channel_out_mono, audioformat.encoding_pcm_16bit, bsize, audiotrack.mode_stream);                         at.play();              int count = 0;             byte[] buffer = new byte[bsize];              time = system.currenttimemillis();              try {                 while (!ismusicstopped && (count = dis.read(buffer, 0, bsize)) >= 0) {                       log.d("time elapsed", ""+(system.currenttimemillis()-time));                     time = system.currenttimemillis();                      //windowing                     stft.framebuffer(buffer);                      //fourier transform , inverse                     stft.fourieranalysis();                      // overlapp-add                     stft.buildbuffer(buffer);                      at.write(buffer, 0, count);                 }                  if (at != null) {                     at.stop();                     at.flush();                     at.release();                     @ = null;                 }                  if (dis != null) {                     dis.close();                     dis = null;                 }                  if (is != null) {                     is.close();                     = null;                 }                  if (stft != null) stft = null;              } catch (ioexception e) {                 // todo auto-generated catch block                 e.printstacktrace();             }         }     };       private void stop() {         ismusicstopped = true;         playthread = null;     }      @override     public boolean oncreateoptionsmenu(menu menu) {         // inflate menu; adds items action bar if present.         getmenuinflater().inflate(r.menu.main, menu);         return true;     }      @override     protected void onpause() {         this.stop();         super.onpause();     }      @override     protected void ondestroy() {         this.stop();         super.ondestroy();     }  } 

stft.java

package com.example.fileoutjava;  import java.nio.bytebuffer; import java.nio.byteorder;  import android.util.log;  import com.badlogic.gdx.audio.analysis.fft;  public class stft {      private int fs, fl; //frame shift , frame length in ms     private int n_fs, n_fl; //frame shift , length in samples     private int buf_len; //length of buffer array (bytes)     private int data_len; //length of buffer array (converted short)     private int padded_data_len; //put 0 padding before , after buffer short[] data     private float n_segs; //number of frames can taken 1 buffer array     private float[][] stft_matrix;     private float[] window; //hamming coefficient     private float norm_factor = 0;     private boolean search_norm_factor = true;     private fft fft;     private int i,j,k; //index loops     private bytebuffer bb;     private float[] tmp_buf;     private float[] tmp_fft;     private float[] tmp_ifft;      public stft(int frame_shift, int frame_length, int freq, int buf_len) {         fs = frame_shift;         fl = frame_length;         this.buf_len = buf_len;         this.data_len = buf_len/2;                //compute values ms samples         n_fs = (int) math.floor(fs*freq/1000);         n_fl = (int) math.floor(fl*freq/1000);          padded_data_len = 2*n_fl + data_len;          //create coefficients         window = hamming(n_fl);          tmp_buf = new float[padded_data_len];         bb = bytebuffer.allocatedirect(2);         bb.order(byteorder.little_endian);          //compute how many frames can extracted buffer         n_segs = 1 + (float) (math.ceil((this.padded_data_len-n_fl)/n_fs));          //data matrix: size of frame (with padding previous frame) * number of segments         stft_matrix = new float[n_fl][(int)n_segs];          log.d("stft stats", "buflen:"+this.buf_len+" // flen:"+n_fl+" // fsh:"+n_fs+                 " // nsegs:"+n_segs);          //initialize fft object         fft = new fft(n_fl*2,freq);          //buffers fft data, 0 padding         tmp_fft= new float[n_fl*2];         tmp_ifft = new float[n_fl];          (int i=0; i<n_fl*2; i++) {             tmp_fft[i] = 0;             tmp_ifft[i/2] = 0;         }       }      //frames whole buffer stft matrix     public void framebuffer(byte[] buf) {          //initialize tmp_buffer , add 0 padding         (k=0; k<padded_data_len; k++)             tmp_buf[k] = 0;          //fill short[] buffer converting byte[] buffer          (i=0; i<buf_len; i+=2) {             bb.position(0);             bb.put(buf[i]);             bb.put(buf[i+1]);             tmp_buf[n_fl+i/2] = (float) bb.getshort(0);         }           //frame short[] buffer matrix using windowing         (j=0; j<n_segs; j++) {             (int i=0; i<n_fl; i++) {                 stft_matrix[i][j] = tmp_buf[j*n_fs+i]*window[i];                  //normalization factor retrieval: first time                 if (search_norm_factor && (j*n_fs+i) == 512)                     norm_factor+=window[i];             }         }          if (search_norm_factor)             norm_factor *= 1.2;         //retrieve norm factor first time         search_norm_factor = false;      }      //sums frames stft matrix 1 buffer     public void buildbuffer(byte[] output) {          //initialize tmp_buffer , add 0 padding         (k=0; k<padded_data_len; k++)             tmp_buf[k] = 0;          //overlap-add         (j=0; j<n_segs; j++) {             (i=0; i<n_fl; i++) {                 tmp_buf[j*n_fs+i] += stft_matrix[i][j];             }         }          //convert short[] byte[] (with normalization)         (i=0; i<buf_len; i+=2) {             bb.position(0);             bb.putshort( (short) (tmp_buf[n_fl+i/2]/norm_factor) );             output[i] = bb.get(0);             output[i+1] = bb.get(1);         }      }      //fft , ifft of buffer     public void fourieranalysis() {          (j=0; j<n_segs;j++) {              (i=0; i<n_fl; i++) {                 tmp_fft[i] = stft_matrix[i][j];             }              fft.forward(tmp_fft);             //operations on spectrum ?             fft.inverse(tmp_ifft);               (int i=0; i<n_fl; i++) {                 stft_matrix[i][j] = tmp_ifft[i];             }         }        }       //utility method hamming coefficients     private float[] hamming(int len){         float[] win = new float[len];         (i=0; i<len; i++){             win[i] = (float) (0.54-0.46*math.cos((2*math.pi*i)/(len-1)));         }          return win;     }  } 

the beginning of answer https://stackoverflow.com/a/10679174/987358 explains it: heap increases necessary , @ app start there isn't needed more.


Comments

Popular posts from this blog

c# - DetailsView in ASP.Net - How to add another column on the side/add a control in each row? -

javascript - firefox memory leak -

Trying to import CSV file to a SQL Server database using asp.net and c# - can't find what I'm missing -