com.android.internal.policy.impl.PhoneLayoutInflater有时会留在内存中(hprof转储)

时间:2010-06-30 13:27:36

标签: android

我正在检查内存,试图通过hprof转储找到最终的内存泄漏。

我发现有时候当我通过后退按钮(完成活动)离开活动时,活动仍会保留在内存中,但它只有两个GC根,这似乎不是很“强”虽然。

这是我的活动流程/我点击并测试的方式:

A,B,C是活动。

1)A - > B - > (返回)A

2)执行hprof转储,结果如下:

B仍然在内存中 ,B活动的GC根目录中唯一的元素是:

com.myapp.android.activity.directory.B

  • mContext of com.android.internal.policy.impl.PhoneLayoutInflater

    • android.app.ContextImpl的mLayoutInflater [Stack Local]

      • java.lang.Thread的[局部变量] [主题]“主要”
  • android.app.ContextImpl的mOuterContext [Stack Local]

    • java.lang.Thread的[局部变量] [主题]“主要”

(线程“main”似乎是UI线程)

继续A:

3)A - > C - > (返回)A

4)使用以下结果执行hprof转储(按预期方式):

B不再在内存中,C不再在内存中,只有A

现在我的问题是: 这个PhoneLayoutInflater来自哪里/为什么当我从B返回到A时它会留在内存中,但是在进一步转到C并返回到A后它会消失。

显然PhoneLayoutInflater用于膨胀视图,我知道它的目的。我只是不明白为什么它会通过主UI线程中的GC根目录保存在内存中。

当我检查上面列出的GC根

  

java.lang.Thread的[局部变量]   [主题]“主要

它将具有以下内容:

  • m.iThread of com.myapp.android.activity.main。 A [Stack Local]
    • ....
      • 这个$ 0 of android.view.inputmethod.InputMethodManager $ ControlledInputConnectionWrapper [JNI Global]

我从A调用活动B和C的方式是通过常规startActivity(intent)

为什么活动A的主UI线程会以某种方式与活动B相关联并被引用?

2 个答案:

答案 0 :(得分:0)

这是我最终做的事情,但我仍然不满意我正在使用反射来解决这个问题。任何人??

public static boolean ReleaseActivityContext(Context context)
{                       
    LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);     
    Class<?> i = inflater.getClass();

    try 
    {    
        Field f = i.getSuperclass().getDeclaredField("mContext");
        f.setAccessible(true); // prevent IllegalAccessException
        f.set(inflater, null); // can cause IllegalAccessException
        return true;    
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }   
    return false;   
}

答案 1 :(得分:0)

我遇到了同样的问题,我使用Eclipse MAT来分析hprof,我花了8个多小时,最后我发现有一些简单的规则要遵循。

  

不要长期保持对a的引用   上下文活动(对...的引用)   活动应该有相同的生命   循环作为活动本身)

     

尝试使用context-application   而不是上下文活动。

     

避免使用非静态内部类   活动,如果你不控制他们的   生命周期,使用静态内部类   并提到一个弱的参考   里面的活动。

请按以下步骤操作: enter image description here

然后点击...... enter image description here

你可以看到物体留在记忆中的原因 enter image description here

现在修改你的代码,看看为什么在不需要它们的情况下存在一些引用。然后在后面按键按下那些引用和中提琴..世界将再次看起来很漂亮:)