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 android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

Reply via email to