I am running my app with StrictMode activated in development as documented here StrictMode for lower platform versions and noticed an error message that I do not know what to think about nor can I find any reference.
I get a android.os.StrictMode$InstanceCountViolation
with values for instances
and limit
e.g.
instances=3; limit=2
Now I am wondering:
- A) how is the limit calculated
- B) how can such a violation actually happen and then I would look into evasive actions.
Any ideas?
Remove the line below from on create.
Here is a discussion on google groups about handling the StrictMode InstanceCountViolation. It looks like every different Android version has a different policy so they seem to just disable it. Also the Android docs say about Strict Mode
I think that is what @sri is trying to show with his code.
It's all in the code
The key is
StrictMode.sExpectedActivityInstanceCount
andincrementExpectedActivityCount
anddecrementExpectedActivityCount
:ActivityThread.performLaunchActivity
just after creating the
Activity
instance.ActivityThread.performDestroyActivity
after the activity has been removed from the application.
So the
limit
is less each time an activity is destroyed, however if an instance is leaked the real instance count will be bigger than the limit, to detect if it's leaked they do some GC magic (indecrementExpectedActivityCount
):if after this the GC didn't remove the activity from the app's memory it is considered a leak.
Conclusion
Based on the above the only way to prevent is to make sure there are no references to the offending activity after
onDestroy
. The problem is that some there may be someWeakReference
s which are still accessible through some native objects, which seem to have a different lifecycle. Here's how I came to this conclusion:MyActivity
and seeing the log messageselect * from instanceof full.package.name.of.MyActivity
Workaround
If we increase the count initially we'll have more legroom before it reports the leak for specific classes:
Further reading
WeakReference
sStrictMode
My understanding is that this violation is used to detect memory leaks. So at that point you should only have 2 instances of the class loaded, but the VM found 3.
I have seen this violation in my code also, but my extra instances were all referenced by weak pointers. So I choose to disable this rule.
see the below example it varies based on android version
It seems there might be a bug in the StrictMode checking on some devices.
If an Activity is started, and exited and restarted very quickly, you can get a StrictMode.InstanceCountViolation.
However this is simply because the garbage collector has not yet finalized the first instance of the Activity, meaning there are temporarily 2 (or more) instances in memory.
Calling System.gc() before startActivity() or startActivityForResult() will stop the StrictMode.InstanceCountViolation.
This seems to indicate a bug (or perhaps a feature?) in the StrictMode checking.