我正在运行开发中激活的StrictMode的应用程序,如此处StrictMode for lower platform versions所述
并发现一条错误消息,我不知道要考虑什么,也找不到任何引用。

我得到一个带有android.os.StrictMode$InstanceCountViolationinstances值的limit,例如



现在我想知道:

  • A)极限如何计算
  • B)实际如何发生这种违规行为,然后我将调查回避行为。

  • 有任何想法吗?

    最佳答案

    全部在代码中

    key 是 StrictMode.sExpectedActivityInstanceCount and incrementExpectedActivityCount and decrementExpectedActivityCount :

  • ActivityThread.performLaunchActivity 中调用增量
    在创建Activity实例之后。
  • ActivityThread.performDestroyActivity 中调用减量
    从应用程序中删除 Activity 后。

  • 因此,每次 Activity 被销毁,limit都会减少,但是,如果实例泄漏,则实际实例数将大于限制,以检测是否泄漏,他们会执行一些GC魔术操作(在decrementExpectedActivityCount中):
        System.gc();
        System.runFinalization(); // added in https://github.com/android/platform_frameworks_base/commit/6f3a38f3afd79ed6dddcef5c83cb442d6749e2ff
        System.gc();
    

    如果在此之后GC仍未从应用程序的内存中删除 Activity ,则将其视为泄漏。

    结论

    基于以上所述,唯一的预防方法是确保在onDestroy之后没有对违规 Activity 的引用。问题在于,有些WeakReference仍然可以通过某些 native 对象访问,这些 native 对象似乎具有不同的生命周期。这是我得出此结论的方式:

    MyActivity中退出并查看日志消息后的
  • 进行堆转储(.hprof)
  • 在Eclipse内存分析器中将其打开
  • 运行OQL:select * from instanceof full.package.name.of.MyActivity
  • 使用Ctrl + Click或Shift + Click全选
  • 右键单击并合并所有GC根的最短路径>并包含所有引用

  • 解决方法

    如果我们使用increase the count initially,则在报告特定类的泄漏之前,我们还有更多的保留空间:
    // 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);
    

    进一步阅读
  • WeakReference s
  • Eclipse Memory Analyzer (MAT)
  • History of StrictMode
  • 关于android - Android StrictMode InstanceCountViolation,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5956132/

    10-10 22:31