Hi,
I've identified a memory leak issue managing connection to a service when an
activity is quickly created/destroyed (or possibly quickly resumed/pause; at
least this is what I am thinking based on testing).
I would like some help to understand what is causing this and how to fix it
properly.
This happens when I switch from another app to my app, and the screen
orientation was different (and my activity holding the connection object is not
in the foreground, there is another activity on top of it); the activity that
manages the service connection gets destroyed/created quickly twice (not sure
exactly why it's twice but that's a different problem).
If I do this a few times, I end up with a bunch of activities (the one that
connects to the service) that can't seem to be garbage collected because they
seem to still be referenced by: 'LoadedApk$ServiceDispatcher$DeathMonitor'
objects at the GC root.
I call bind in onResume() and unBind in onPause().
After doing some experiment, I believe the way I bind/unbind somehow the root
cause of the issue. For example if I stop calling unbind, the memory leak stops
but i get some ConnectionLeaked exceptions (I understand their cause).
Maybe calling unbind before the connection object receives a notification is
causing this issue somehow (but I don't see errors in logcat, and the service
properly receives the bind/unbind calls).
Also if I call 'bind' in onStart() and 'unBind' in onStop(), I do not see those
memory leaks anymore (also no issue if I call bind in onCreate() and unbind in
onDestroy()).
I see a bunch of activities instances with the following path to GC root when
i use the Eclipse Memory Analyzer (after I switch back and forth between my app
and another app a few times):
MyActivity
mContext android.app.LoadedApk$ServiceDispatcher @ 0x41059d68
--this$0 android.app.LoadedApk$ServiceDispatcher$DeathMonitor @ 0x4105b548
Native Stack
My source code is basically:
public class MyActivity extends Activity {
private final String TAG = "MyActivity";
public IREventService mREventService;
private ServiceConnection mConnection = new ServiceConnection()
{
// Called when the connection with the service is
established
public void onServiceConnected(ComponentName className,
IBinder service) {
mREventService =
IREventService.Stub.asInterface(service);
Log.e(TAG, "connected to
service:"+MyActivity.this.toString()+ "connection: "+this.toString());
}
// Called when the connection with the service disconnects
unexpectedly
public void onServiceDisconnected(ComponentName className) {
Log.e(TAG, "Service has unexpectedly
disconnected:"+this.toString());
mREventService = null;
}
};
@Override
protected void onResume() {
super.onResume();
Intent intent = new Intent(this,
EventService.class);
intent.setAction(this.toString());
Log.w(TAG, "bindService:"+this.toString());
bindService(intent,
mConnection, Context.BIND_AUTO_CREATE);
}
@Override
protected void onPause() {
super.onPause();
Log.w(TAG, "unbinding from
service:"+this.toString());
unbindService(mConnection);
}
}
The logcats logs look like:
<I switched to another app>
06-17 17:27:08.965: WARN/MyActivity(5987): MyActivity onStop()
<this is where i switch back to my app>
06-17 17:27:09.415: INFO/ActivityManager(154): Config changed: { scale=1.0
imsi=310/4 loc=en_US touch=3 keys=1/1/2 nav=1/2 orien=L layout=0x10000014
uiMode=0x11 seq=169}
06-17 17:29:44.855: WARN/MyActivity(5987): MyActivity onDestroy()
06-17 17:29:44.855: INFO/TabletStatusBar(205): DISABLE_BACK: no
06-17 17:29:45.015: WARN/MyActivity(5987): MyActivity onCreate()
06-17 17:29:45.015: WARN/MyActivity(5987): MyActivity onResume()
06-17 17:29:45.015: WARN/MyActivity(5987): bindService:MyActivity@408753a0
06-17 17:29:45.015: WARN/EventService(6009): onBind() MyActivity@408753a0
06-17 17:29:45.025: WARN/MyActivity(5987): MyActivity onPause()
06-17 17:29:45.025: WARN/MyActivity(5987): unbinding from
service:MyActivity@408753a0
06-17 17:29:45.025: WARN/EventService(6009): onUnBind() MyActivity@408753a0
06-17 17:29:45.025: ERROR/MyActivity(5987): connected to
service:MyActivity@408753a0connection:
com.yogiplay.apps.MyActivity$1@40878328<mailto:com.yogiplay.apps.MyActivity$1@40878328>
06-17 17:29:45.065: DEBUG/dalvikvm(5987): GC_FOR_ALLOC freed 32K, 3% free
31936K/32839K, paused 34ms
06-17 17:29:45.125: DEBUG/dalvikvm(5987): GC_FOR_ALLOC freed 65K, 4% free
32895K/33927K, paused 36ms
06-17 17:29:45.205: DEBUG/dalvikvm(5987): GC_FOR_ALLOC freed 803K, 5% free
33550K/35079K, paused 30ms
06-17 17:29:45.245: DEBUG/dalvikvm(5987): GC_FOR_ALLOC freed 65K, 4% free
34109K/35335K, paused 27ms
06-17 17:29:45.255: INFO/dalvikvm-heap(5987): Grow heap (frag case) to 36.976MB
for 3722256-byte allocation
06-17 17:29:45.285: DEBUG/dalvikvm(5987): GC_FOR_ALLOC freed <1K, 4% free
37744K/38983K, paused 25ms
06-17 17:29:45.335: DEBUG/dalvikvm(5987): GC_CONCURRENT freed <1K, 4% free
37744K/38983K, paused 2ms+3ms
06-17 17:29:45.645: INFO/WindowManager(154): Setting rotation to 3, animFlags=1
06-17 17:29:45.665: INFO/ActivityManager(154): Config changed: { scale=1.0
imsi=310/4 loc=en_US touch=3 keys=1/1/2 nav=1/2 orien=P layout=0x10000014
uiMode=0x11 seq=170}
06-17 17:29:45.685: DEBUG/FlurryAgent(5770): Ending session
06-17 17:29:45.755: WARN/MyActivity(5987): MyActivity onStop()
06-17 17:29:45.755: WARN/MyActivity(5987): MyActivity onDestroy()
06-17 17:29:45.755: WARN/IInputConnectionWrapper(5770): showStatusIcon on
inactive InputConnection
06-17 17:29:45.865: WARN/MyActivity(5987): MyActivity onCreate()
06-17 17:29:45.865: WARN/MyActivity(5987): MyActivity onResume()
06-17 17:29:45.865: WARN/MyActivity(5987): bindService:MyActivity@409e4c00
06-17 17:29:45.875: WARN/EventService(6009): onBind() MyActivity@409e4c00
06-17 17:29:45.875: WARN/MyActivity(5987): MyActivity onPause()
06-17 17:29:45.875: WARN/MyActivity(5987): unbinding from
service:MyActivity@409e4c00
06-17 17:29:45.875: WARN/EventService(6009): onUnBind() MyActivity@409e4c00
06-17 17:29:45.875: ERROR/MyActivity(5987): connected to
service:MyActivity@409e4c00connection:
com.yogiplay.apps.MyActivity$1@409e4d20<mailto:com.yogiplay.apps.MyActivity$1@409e4d20>
06-17 17:29:45.925: DEBUG/dalvikvm(5987): GC_FOR_ALLOC freed 6130K, 18% free
32743K/39815K, paused 24ms
06-17 17:29:46.005: DEBUG/dalvikvm(5987): GC_FOR_ALLOC freed 883K, 16% free
33737K/39815K, paused 23ms
06-17 17:29:46.035: DEBUG/dalvikvm(5987): GC_FOR_ALLOC freed 1K, 15% free
33970K/39815K, paused 23ms
thanks for the help.
Laurent
--
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en