System.gc () вызывает замедление от второго запуска Activity

Я испытываю очень странное явление (тестовое устройство: HTC Desire HD, Android 2.3.5). Я знаю, что System.gc() бесполезен и обескуражен, и я не пытаюсь предлагать иное, но дело в том, что оно также не должно вызывать проблем (то есть оно должно быть бесполезным в лучшем случае ).

У меня есть приложение, которое содержит GLSurfaceView в своей иерархии представлений. GLSurfaceView и добавляется в Activity.onCreate() . Обычно приложение работает следующим образом:

  1. Пользователь запускает приложение и переходит к главному меню
  2. Пользователь выбирает элемент mainmenu, который устанавливает GLSurfaceView в View.VISIBLE
  3. Пользователь играет со встроенной игрой на GLSurfaceView
  4. Пользователь переходит в mainmenu и выходит из действия (=> Activity.finish() )

My Activity.onPause() выглядит так:

 mGameThread.pause(); // gameThread is my custom thread class for the in-built game mGLView.onPause(); // pause the renderer thread 

Пока все хорошо, все работает нормально. Однако проблемы возникают после добавления следующего кода в onPause() (для случая, когда пользователь выходит из игры из onPause() ):

 mGameThread.pause(); // gameThread is my custom thread class for the in-built game mGLView.onPause(); // pause the renderer thread if (isFinishing()) { System.gc(); } 

В деталях: если Activity запущена в первый раз (= т.е. процесс приложения не существовал раньше), все работает нормально. Однако начиная с 2-го начала активности (= после первого выхода из основного меню , т.е. после первого Activity.finish() ), частота кадров GLSurfaceView уменьшается на 40-50% , встроенная игра становится медленной ,

Если я удалю вызов System.gc() , проблема исчезнет. Более того, если я делаю следующее, он также избавляется от проблемы:

 mGameThread.pause(); // gameThread is my custom thread class for the in-built game mGLView.onPause(); // pause the renderer thread if (isFinishing()) { // 1. get layout root of View hierarchy // 2. recursively remove (detach) all Views // 3. call GC System.gc(); } 

Я не добавлял конкретный код, потому что он сложный, поэтому я использовал комментарии. Если я просто отсоединяю GLSurfaceView через removeView() , этого недостаточно. Вся иерархия представлений должна быть очищена.

Обратите внимание, что я не смог найти утечки памяти (нет утечки активности через чертежи / статику и т. Д.). Более того, конечно, gameThread правильно выходит, когда приложение закрыто (я просто не включил его исходный код).

Любые идеи, догадки? По-видимому, System.gc() похоже, вызывает некоторые проблемы для механизма уничтожения активности / макета Android. Опять же, как я уже сказал, если я удалю System.gc() , проблема исчезнет.

Solutions Collecting From Web of "System.gc () вызывает замедление от второго запуска Activity"

У меня есть опыт программирования игр для Android. Я использовал, чтобы очистить все представление в иерархии, потому что при запуске потоков, если вы вызываете System.gc (), иногда бывает, что ваш поток ссылается на некоторые ваши взгляды, даже если вы вызываете system.gc (), это представление не будет Удалите, и если вы продолжаете играть снова и снова в этой игре, вы заметите, что ваша память кучи начинает расти.

Это зависит от утечки памяти, если вы просачиваете некоторую память в КБ, потребуется больше времени для краха вашей игры. Лучший способ использовать Eclipse Memory Anlyser (Eclipse MAT) и сравнить ваши стеки.

Шаг 1: сделайте снимок памяти при первом запуске игры. Шаг 2: сделайте снимок памяти, когда вы начнете игру второй раз. Step3: Теперь сравните оба стека снимков, это скажет вам разницу.

Это очень полезный инструмент. У меня были огромные проблемы с памятью в моей игре Apache Attack . Я исправил их, используя этот потрясающий инструмент. Следуйте этому учебному курсу ECLIPSE MAT