2010-06-30 3 views
7

Я проверяю память, пытаясь найти возможные утечки памяти через дампы hprof.com.android.internal.policy.impl.PhoneLayoutInflater иногда остается в памяти (hprof dumps)

Я нахожу, что иногда, когда я оставляю активность через кнопку «Назад» (которая завершила бы действие), активность все равно останется в памяти, но она будет иметь только один корень GC, который не кажется очень «сильным» ' хоть.

Это моя активность потока/путь я нажимаю и тест:

A, B, C оздоровительная деятельность.

1) А -> В -> (обратно)

2) общего между HPROF дамп со следующим результатом:

B все еще находится в памяти, единственные элементы в GC корень B активности являются:

com.myapp.android.activity.directory.B

  • mContext из com.android.internal.policy.impl.PhoneLayoutInflater

    • mLayoutInflater из android.app.ContextImpl [Stack Local]

      • [локальная переменная] Явы .lang.Thread [тема] "главный"
  • mOuterContext из android.app.ContextImpl [Stack Local]

    • [локальная переменная] из java.lang.Thread [Тема] "главный"

(Thread «главный ", кажется, поток пользовательского интерфейса)

продолжают от А:

3) А -> с -> (BAC K к нему)

4) общего между HPROF дамп со следующим результатом (как ожидалось):

В не в памяти больше, С не в памяти больше, только

Теперь мой вопрос: , где этот PhoneLayoutInflater исходит из/почему он остается в памяти, когда я возвращаюсь из B в A, но он исчезнет после того, как отправится дальше на C и вернется обратно к A.

Очевидно, что PhoneLayoutInflater предназначен для раздувания представлений, я знаю о его цели. Я просто не понимаю, почему он будет храниться в памяти через корень GC из основного потока пользовательского интерфейса.

Когда я проверяю GC корни выше перечисленных

[локальная переменная] из java.lang.Thread [Thread] «главный

он будет иметь следующее:

  • mUiThread of com.myapp.android.activity.main. A [Stack Local]
    • ....
      • это $ 0 из android.view.inputmethod.InputMethodManager $ ControlledInputConnectionWrapper [JNI Global]

Так я называю деятельность B и С из А осуществляется через регулярный startActivity(intent)

Почему основной поток пользовательских интерфейсов как-то связан и связан с активностью B?

+0

http://android-developers.blogspot.com/2009/01/avoiding-memory-leaks.html может быть уместным. – fadden

+0

спасибо за ссылку, но я читал это уже много раз. нет ссылки на поток UI другого действия, также я не знаю, где «этот $ 0 ofroid.view.inputmethod.InputMethodManager $ ControlledInputConnectionWrapper [JNI Global]». Это странно. –

+0

У меня такая же проблема с телефономLayoutInflater. Раньше я использовал рефлексию, чтобы вымыть такие причуды памяти в андроиде (как правило, связанные с списками), но я не знаю, что, черт возьми, вызывает это или то, что я мог бы отразить до нуля, не используя мое приложение. Собираемся добавить щедрость к этому. –

ответ

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; 
} 
0

У меня была та же проблема, и я использовал Eclipse, MAT анализировать HPROF, я провел в течение 8 часов, и, наконец, я узнал, что есть некоторые простые правила, чтобы следовать.

Не хранить долгоживущие ссылки на контекстно-активности (ссылки на деятельность должна иметь такую ​​же жизнь цикл, как и сама деятельность)

Try с помощью контекстного приложения вместо контекстной активности.

Избегайте нестатические внутренние классы в качестве активности, если не контролировать их жизненного цикла, используют статический внутренний класс и сделать слабую ссылку на активности внутри.

Выполните следующие действия: enter image description here

Затем нажмите ...

вы можете увидеть причину объектов оставаться в памяти enter image description here

Теперь пересмотреть свой код и посмотреть, почему есть некоторые ссылки существует, когда нет необходимости в них существовать. затем на задней клавише нажмите «аннулировать эти ссылки и альта». Мир снова будет выглядеть красиво :)

+0

Я использую Eclipse MAT для анализа памяти. –

+0

Aizaz, спасибо за сообщение. У меня не было времени попробовать решение, которое вы разместили. работая хорошо? Насколько я помню, не было контекста активности, а использовался только контекст приложения, когда я проходил какой-либо контекст. btw - вот новое сообщение в блоге на Android по анализу памяти: http://android-developers.blogspot.com /2011/03/memory-analysis-for-android.html –

+0

Я использую yourkit.com для анализа mem, также хороший инструмент, но не бесплатный. –

Смежные вопросы