Есть ли утечка памяти в библиотеке Android ZXing?


Я написал приложение для Android, используя библиотеку ZXing, и я получаю java.lang.OutOfMemoryError.

Во-первых, я был уверен, что ошибка была на моей стороне, поэтому я использовал Eclipse Memory Analyzer (MAT) в соответствии с Patrick Dubroy Google I/O 2011: Memory management for Android Apps и несколько других учебников о том, как отслеживать утечки памяти, такие как утечки памяти Android или различные способы утечки.

В мате я обнаружил, что со временем сотни экземпляров com.google.zxing.common.BitMatrix заняли большую часть моего память кучи.

Удивительно, но я испытываю ту же проблему в оригинальной тестовой программе ZXing "CaptureActivity"!

После некоторого исследования у меня есть ключ, что ссылка на действие в классе DecodeHandler может помешать сборщику мусора освободить BitMatrix. Но у меня слишком мало опыта, чтобы это проверить. Более того, я удивлен, что нахожу эту проблему в оригинальной библиотеке ZXing (версия 2.1).

Может ли кто-нибудь воспроизвести это явление или пережил это было раньше?

2 3

2 ответа:

Я думаю, что вы находитесь на правильном пути. Вам нужно продолжать смотреть в профиль кучи мата, чтобы определить, какая часть пользовательского кода содержит ссылки на DecodeHandler и транзитивно на BitMatrix. Попробуйте проследить за входящими ссылками из BitMatric, вычислить деревья доминаторов и проверить подозреваемых в утечке.

Попробуйте профилировать приложение, чтобы увидеть, какая часть кода отвечает за выделение BitMatrix, попробуйте отследить его обратно в код приложения.

Тот факт, что в Примере CaptureActivity та же проблема может быть вызвана неправильным использованием библиотеки, поэтому это не обязательно доказывает, что lib пропускает память. Например, библиотека могла быть обновлена, а пример остался прежним.

Я нашел ту же проблему (в версии 2.3 ZXing), работающую на эмуляторе Android (версия Intel). Первопричиной, по-видимому, было следующее: В методе selectBestPatterns класса FinderPatternFinder, a NotFoundException выбрасывается, когда не найден действительный (QR) шаблон finder. Это исключение ловится в методе decodeInternal класса MultiFormatReader. Это исключение, таким образом, пропускает нормальное возвращение нескольких вызовов метода. Я обнаружил, что из-за этого" исключительного возврата " экземпляр FinderPatternFinder не освобождается, и этот экземпляр в поворот держится на ссылке BitMatrix, которая использует довольно много памяти. Звучит безумно, и я не думаю, что это соответствует спецификации Java, поэтому я называю это ошибкой в эмуляторе. Обходной путь состоит в том, чтобы не полагаться на исключение для сигнала о том, что шаблон finder не был найден. Я сделал это, вернув несколько нулевых результатов при сворачивании стека вызовов методов. Это полностью решило проблему утечки памяти.