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

Mat*_*adt 8 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 [Thread]"main"的[局部变量]
  • android.app.ContextImpl的 mOuterContext [Stack Local]

    • java.lang.Thread [Thread]"main"的[局部变量]

(线程"主"似乎是UI线程)

继续从A:

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

4)执行具有以下结果的hprof转储(如预期的那样):

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

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

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

当我检查上面列出的GC根

[local]的java.lang.Thread [Thread]"main

它将具有以下内容:

  • com.myapp.android.activity.main的mUiThread.A [Stack Local]
    • ....
      • 这个$ 0的android.view.inputmethod.InputMethodManager $ ControlledInputConnectionWrapper [JNI Global]

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

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

Tyl*_*ale 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;   
}
Run Code Online (Sandbox Code Playgroud)