android - Why won't my Threads die and cause a memory leak? -


an app of mine accumulating lot of thread instances gc can't pick , clear out. memory leak crashes app in long run.

i'm not 100% sure come from, have distinct feeling following might code in question:

public class urahosthttpconnection extends abstracturahostconnection {     private handler uithreadhandler = new handler(looper.getmainlooper());     private executor taskexecutor = new executor() {          public void execute(runnable command) {              new thread(command).start();         }     };     private connectiontask task = null;      @override     public void sendrequest(final httpurirequest request) {         this.task = new connectiontask();         this.uithreadhandler.post(new runnable() {             public void run() {                 task.executeonexecutor(taskexecutor, request);             }         });    }      @override     public void cancel() {         if (this.task != null)             this.task.cancel(true);     } } 

this code allows me run several http connections in parallel won't block each other on default asynctask executor (which single threaded queue).

i checked, asynctasks in fact reaching onpostexecute() methods , don't run forever. after inspecting memory dumps suspect wrapping thread-objects not stop running after asynctasks completed.

is possible above code still responsible memory leak, or should start looking elsewhere?

any appreciated.

edit: should noted, sendrequest ever called once. other parts of code not in sample above make sure of that.

edit 2: super-class looks this:

public abstract class abstracturahostconnection {     protected iurahostconnectionlistener listener = null;      public void setlistener(iurahostconnectionlistener listener) {         this.listener = listener;     }     public abstract void sendrequest(httpurirequest request);     public abstract void cancel(); } 

the asynctask looks this:

private class connectiontask extends asynctask<httpurirequest, object, void> {     final byte[] buffer = new byte[2048];     private bytearraybuffer receiveddatabuffer = new bytearraybuffer(524288);      @override     protected void doinbackground(httpurirequest... arg0) {         urahosthttpconnection.taskcounter++;         androidhttpclient httpclient = androidhttpclient.newinstance("ivu.realtime.app");         try {             // response , notify listener             httpresponse response = httpclient.execute(arg0[0]);             this.publishprogress(response);              // check status code ok before proceeding             if (response.getstatusline().getstatuscode() == 200) {                 httpentity entity = response.getentity();                 inputstream inputstream = entity.getcontent();                 int readcount = 0;                  // read 1 kb of data , hand on listener                 while ((readcount = inputstream.read(buffer)) != -1 && !this.iscancelled()) {                     this.receiveddatabuffer.append(buffer, 0, readcount);                     if (this.receiveddatabuffer.length() >= 524288 - 2048) {                         this.publishprogress(receiveddatabuffer.tobytearray());                         this.receiveddatabuffer.clear();                     }                 }                  if (this.iscancelled()) {                     if (arg0[0] != null && !arg0[0].isaborted()) {                         arg0[0].abort();                     }                 }             }         } catch (ioexception e) {             // forward errors listener             e.printstacktrace();             this.publishprogress(e);         } {             if (httpclient != null)                 httpclient.close();         }          return null;     }      @override     protected void onprogressupdate(object... payload) {         // forward response         if (payload[0] instanceof httpresponse)             listener.onreceiveresponse((httpresponse) payload[0]);         // forward error         else if (payload[0] instanceof exception)             listener.onfailwithexception((exception) payload[0]);         // forward data         else if (payload[0] instanceof byte[])             listener.onreceivedata((byte[]) payload[0]);     }      @override     protected void onpostexecute(void result) {         listener.onreceivedata(this.receiveddatabuffer.tobytearray());         listener.onfinishloading();         urahosthttpconnection.taskcounter--;         log.d(tag, "there " + urahosthttpconnection.taskcounter + " running connectiontasks.");     } } 

substitute threadpoolexecutor executor have control on size of pool. if threadpoolexecutor executor exposed methods, may case default maximum pool size set high.

official doc here.

take in particular at:

setcorepoolsize(int corepoolsize) //sets core number of threads.  setkeepalivetime(long time, timeunit unit) //sets time limit threads may remain idle before being terminated.  setmaximumpoolsize(int maximumpoolsize) //sets maximum allowed number of threads. 

there's alternative if want code less (better idea depending on how control want , how code you'll trade it).

executor taskexecutor = executors.newfixedthreadpool(x); 

where x = size of pool


Popular posts from this blog

How to calculate SNR of signals in MATLAB? -

c# - Attempting to upload to FTP: System.Net.WebException: System error -

ios - UISlider customization: how to properly add shadow to custom knob image -