Я нашел утечку памяти в Android 5.x Camera2 API, который также reported. Проблема в том, что вы используете устройство Android Lollipop, которое имеет API Camera2, реализованный в режиме LEGACY
. На таких устройствах, вызывающий context.getSystemService(Context.CAMERA_SERVICE)
, вызывает context
, чтобы он не собирался мусором.Как избежать утечки памяти в контексте.getSystemService (Context.CAMERA_SERVICE)?
Если это context
- это ваша деятельность, которая запускается несколько раз, вы можете в конечном итоге повесить ссылки на десятки экземпляров вашей деятельности, которые никогда не собираются с мусором.
Проблема, как представляется, происходит только на Lollipop устройств, которые имеют Camera2 API реализованы в LEGACY
режиме (например, HTC One M8, Samsung Galaxy S4), в то время как это не происходит на Samsung Galaxy S6, который реализует Camera2 API в режиме FULL
.
Чтобы продемонстрировать проблему, я создал small demo app. Приложение содержит два действия: сначала содержит кнопку, которая вызывает второе действие. Второе действие получает CameraManager
и запрашивает уровень поддержки Camera2 API для первой обратной камеры и возвращает результат для первой активности. Если запустить приложение на устройстве, которое реализует Camera2 API в режиме LEGACY
, после нажатия на кнопку 98 раз, в результате чего GC и затем сбрасывая HPROF вы увидите ровно 98 живых экземпляров из Main2Activity
, как этот http://www.pohrani.com/f/1H/gs/4EFlHKoj/sgs4.png
Если вы делаете то же самое на устройстве, которое реализует Camera2 API в режиме FULL
, вы увидите 0 текущих экземпляров Main2Activity
, вот так http://www.pohrani.com/f/2q/bV/4srUZIJL/sgs6.png
Есть ли способ обхода этой утечки?
Можно спросить, почему я это делаю? В нашей компании мы разрабатываем barcode and OCR scanning solutions, а также знаменитый PhotoMath app. Таким образом, у нас есть активность сканирования, которая контролирует процесс камеры и сканирования. При запуске, активность проверяет, поддерживает ли устройство Camera2 API в или LIMITED
, и пытается использовать его для повышения производительности, тогда как если Camera2 API находится в режиме LEGACY
, то мы предпочитаем использовать управление камерой с использованием старого API-интерфейса камеры, как мы это делаем до-Lollipop устройств.
Из-за упомянутой утечки памяти, когда клиент, который интегрировал наш SDK в свое приложение, запускает операцию сканирования, выполняет сканирование и получает результат, один экземпляр активности сканирования будет просачиваться из-за ошибки. Если клиент сканирует много, это может съесть более 20 МБ памяти - серьезная проблема!
Так что если кто-то знает, как сделать обходной путь для этой проблемы, я буду бесконечно благодарен!
Я собирался опубликовать тот же ответ :) –
Отличная идея! Работает как шарм :-) – DoDo