Question

I am having issue with memory after running many times my app.

java.lang.OutOfMemoryError: bitmap size exceeds VM budget

I figure I was leaking memory somehow so I did a DUMP HPROF file and used the MAT tool to figure out what was wrong. It turns out that after running like 5 times the app and quiting, I find 5 instances of my Activity and 5 instances of PhoneStateListener.

If I remove the call to PhoneStateListener, I don't have that issue anymore and I see just 1 instance of my Activity.

The question is, how do I resolve this?

Thanks

Daniel


Here is my code:

OnCreate method:

telephonyManager.listen(mPhoneListener,
                PhoneStateListener.LISTEN_SERVICE_STATE
                | PhoneStateListener.LISTEN_SIGNAL_STRENGTH
                | PhoneStateListener.LISTEN_CALL_STATE
                | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
                | PhoneStateListener.LISTEN_DATA_ACTIVITY); 

on the Activity class:

PhoneStateListener mPhoneListener = new PhoneStateListener() {
        public void onCallStateChanged(int state,
                java.lang.String incomingNumber) {
        //do something
    }
}

on onDestroy method:

telephonyManager.listen(mPhoneListener, PhoneStateListener.LISTEN_NONE);        
mPhoneListener = null;
Was it helpful?

Solution

onDestroy is not guaranteed to get called. Source: onDestroy Docs

You should try cleaning up on onPause and then onResume re-instate the stuff you need. This will help clean up some memory pressure and leaks.

OTHER TIPS

The answer above is not correct: onDestroy() is not a problem here as killing the process will obviously free all memory and binders.

There is one very important element you have to take into consideration here. The binder registered with the telephony manager will only be released after the associated binder object in the system process has been released. This can be long after correctly unregistering the listener, because it may take some time before the next GC run in the system process reclaims the object and with that the reference to your listener.

The best thing you can do is to manually remove the references from the listener to other objects when you're done with it in onDestroy().

PhoneStateListener mPhoneListener = new PhoneStateListener() 
{ 
    public void onCallStateChanged(int state, java.lang.String incomingNumber) 
    { 
    //do something 

     telephonyManager.listen(mPhoneListener, PhoneStateListener.LISTEN_NONE); 
     mPhoneListener = null;
    } 
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top