I have a memory leak using ListActivity in Android
I have an application that uses a Service and some list activities. When the activities are opened, I can see the heap usage increase in DDMS, when the activities are closed, the heap usage decreases slightly. The service is still running in the background at this point. If the activity is started again by re-running the application and the closed, the heap usage increases again then decreases, but never returns to the original level before the activity was first opened. If it repeatedly (10-15 times) open the activity then close the activity, the heap size (both MB and # Objects) balloons!
I'd expect ListActivity's onDestroy to take care of itself when it gets destroyed. What am I missing with this? Am I using ListActivity incorrectly?
A test app similar to my real code is below. Create a new android application, add this to the manifest:
<service android:name="LeakTestService"/>
and these java files:
LeakTestActivity.java ------------- package LeakTest.Test; import java.util.ArrayList; import java.util.HashMap; import android.app.Activity; import android.app.ListActivity; import android.content.Intent; import android.os.Bundle; import android.widget.ArrayAdapter; import android.widget.SimpleAdapter; public class LeakActivity extends ListActivity { ArrayList> _Data=new ArrayList>(); ArrayAdapter _Adapter; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Intent svc = new Intent(this.getApplicationContext(), LeakTestService.class); startService(svc); // the problem happens with both SimpleAdapter and ArrayAdapter //_Adapter = new SimpleAdapter(this.getApplicationContext(), _Data, android.R.layout.two_line_list_item, new String[] { "line1","line2" }, new int[] { android.R.id.text1, android.R.id.text2 }); _Adapter = new ArrayAdapter(this.getApplicationContext(), android.R.layout.simple_l开发者_Python百科ist_item_1, new String[] {"data1","data2"} ); // if this line is removed, the heap usage never balloons if you repeatedly open+close it getListView().setAdapter(_Adapter); } @Override public void onDestroy() { _Adapter=null; // this line doesn't help getListView().setAdapter(null); // neither does this line super.onDestroy(); } } LeakTestService.java -------- package LeakTest.Test; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.widget.Toast; public class LeakTestService extends Service { @Override public void onStart(Intent intent, int startId) { Toast.makeText(getBaseContext(), "Service onStart", Toast.LENGTH_SHORT).show(); } @Override public void onDestroy() { Toast.makeText(getBaseContext(), "Service onDestroy", Toast.LENGTH_SHORT).show(); } @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return null; } }
I had the very same problem but I found out that the problem only occurred when I was debugging. On a "normal" run all the activities are gone.
If it repeatedly (10-15 times) open the activity then close the activity, the heap size (both MB and # Objects) balloons!
Have you run the garbage collector? There's a button for that in DDMS.
Once you have run the garbage collector and it seems to be coming up with nothing to collect (as logged in LogCat), you can always dump the heap and inspect it with MAT or jhat.
Am I using ListActivity incorrectly?
Delete all occurrences of getApplicationContext()
in your activity and replace them with this
. The activity is a Context
, and you want to be using the Activity
in those places.
Similarly, I don't know why you are calling getBaseContext()
in the Service
, rather than just using this
, since Service
too is a Context
.
精彩评论