Я испытываю очень странное явление (тестовое устройство: HTC Desire HD, Android 2.3.5). Я знаю, что System.gc()
бесполезен и обескуражен, и я не пытаюсь предлагать иное, но дело в том, что он не должен вызывать проблем либо (т.е. Он должен быть бесполезен максимум).
У меня есть приложение, которое содержит GLSurfaceView
в своей иерархии представлений. GLSurfaceView
создается и добавляется в Activity.onCreate()
. Обычно приложение работает следующим образом:
- Пользователь запускает приложение и переходит к главному меню
- Пользователь выбирает элемент mainmenu, который устанавливает
GLSurfaceView
вView.VISIBLE
- Пользователь играет со встроенной игрой на
GLSurfaceView
- Пользователь переходит в mainmenu и выдает активность (= >
Activity.finish()
)
Мой Activity.onPause()
выглядит следующим образом:
mGameThread.pause(); // gameThread is my custom thread class for the in-built game
mGLView.onPause(); // pause the renderer thread
Пока все хорошо, все работает нормально. Однако возникают проблемы после добавления следующего кода в 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()
, похоже, вызывает некоторые проблемы для механизма уничтожения Activity/layout для Android. Опять же, как я уже сказал, если я удалю System.gc()
, проблема исчезнет.