Android的StrictMode InstanceCountViolation [英] Android StrictMode InstanceCountViolation
问题描述
我正在我与StrictMode开发启动应用程序的记录在这里 StrictMode较低的平台版本 并注意到,我不知道该怎么去想我也不能找到任何引用的错误消息。
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.
我收到了 android.os.StrictMode $ InstanceCountViolation
与实例值
和限
如:
实例= 3;极限= 2
instances=3; limit=2
现在我想知道:
- A)是如何计算的限制
- B)怎么能这样违反实际发生,那么我会考虑规避动作。
任何想法?
推荐答案
关键是<一个href="https://github.com/android/platform_frameworks_base/blob/master/core/java/android/os/StrictMode.java#L1970"><$c$c>StrictMode.sExpectedActivityInstanceCount$c$c>和 incrementExpectedActivityCount
和 decrementExpectedActivityCount
:
It's all in the code
The key is StrictMode.sExpectedActivityInstanceCount
and incrementExpectedActivityCount
and decrementExpectedActivityCount
:
- 在增量被称为<一个href="https://github.com/android/platform_frameworks_base/blob/89764e337b6c11fb7ed919f563bcf1ceac92e364/core/java/android/app/ActivityThread.java#L2201"><$c$c>ActivityThread.performLaunchActivity$c$c>
刚过创建活动
实例。 - 在递减被称为在<一个href="https://github.com/android/platform_frameworks_base/blob/89764e337b6c11fb7ed919f563bcf1ceac92e364/core/java/android/app/ActivityThread.java#L3678"><$c$c>ActivityThread.performDestroyActivity$c$c>
后的活性已经从应用程序中删除。
- Increment is called in
ActivityThread.performLaunchActivity
just after creating theActivity
instance. - Decrement is called in
ActivityThread.performDestroyActivity
after the activity has been removed from the application.
因此,限制
少每次的活动被破坏,但是如果一个实例被泄露了真正的实例数量将超过极限,以检测它是否泄露他们做一些GC魔术(在 decrementExpectedActivityCount
):
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 (in decrementExpectedActivityCount
):
System.gc();
System.runFinalization(); // added in https://github.com/android/platform_frameworks_base/commit/6f3a38f3afd79ed6dddcef5c83cb442d6749e2ff
System.gc();
如果在此之后在GC未从应用程序的存储器它被认为是泄漏除去活性
if after this the GC didn't remove the activity from the app's memory it is considered a leak.
根据以上至prevent的唯一方法是确保有后的onDestroy
没有提到违规活动。问题是,有些可能有一些的WeakReference
■哪些仍然通过一些本地对象,这似乎有不同的生命周期进行访问。以下是我得出这样的结论:
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 some WeakReference
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
打了退堂鼓,看到日志消息之后 - 请堆转储(.hprof)
- 在打开的的Eclipse内存分析器的
- 运行OQL:
SELECT *的instanceof full.package.name.of.MyActivity
- 选择全部用<大骨节病>按Ctrl +点击骨节病>或<大骨节病> Shift +单击
- 右键单击和合并到GC根的最短路径>所有引用的
- after backing out from
MyActivity
and seeing the log message - make a heap dump (.hprof)
- open it in Eclipse Memory Analyzer
- run OQL:
select * from instanceof full.package.name.of.MyActivity
- select all with Ctrl+Click or Shift+Click
- right click and Merge Shortest Path to GC Roots > with all references
如果我们增加计数最初,我们将有更多的腿部空间就报告泄漏的具体上课前:
If we increase the count initially we'll have more legroom before it reports the leak for specific classes:
// Application.onCreate or nearby where you set up StrictMode detectActivityLeaks
Method incrementExpectedActivityCount = StrictMode.class.getMethod("incrementExpectedActivityCount", Class.class)
incrementExpectedActivityCount.invoke(null, MyActivity.class);
incrementExpectedActivityCount.invoke(null, MyActivity2.class);
进一步阅读
- <一个href="https://weblogs.java.net/blog/2006/05/04/understanding-weak-references"><$c$c>WeakReference$c$c>s
- 的Eclipse内存分析器(MAT)
- <一个href="https://github.com/android/platform_frameworks_base/blame/master/core/java/android/os/StrictMode.java">History对
StrictMode
WeakReference
s- Eclipse Memory Analyzer (MAT)
- History of
StrictMode
Further reading
这篇关于Android的StrictMode InstanceCountViolation的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!