質問

I have written an Android app using the ZXing library and I am getting an java.lang.OutOfMemoryError.

First, I was sure the error was on my end, so I used the Eclipse Memory Analyzer (MAT) according to Patrick Dubroy Google I/O 2011: Memory management for Android Apps and several other tutorials on how to track down memory leaks, like Android Memory Leaks OR Different Ways to Leak.

In MAT I found that over time hundreds of instances of com.google.zxing.common.BitMatrix occupied most of my heap memory.

Surprisingly, I experience the same problem in the original ZXing test program "CaptureActivity"!

After some investigation I have a clue that the activity reference in the DecodeHandler class might keep the garbage collector from freeing the BitMatrix. But I have too little experience to verify this. Moreover I am surprised that I find this problem in the original ZXing library (version 2.1).

Can anyone reproduce this phenomenon or has experienced it before?

役に立ちましたか?

解決

I think you are on the right track. You need to keep looking into the MAT heap profile to determine which part of the user code is holding references to the DecodeHandler and transitively to the BitMatrix. Try to follow the incoming references from the BitMatric, compute dominator trees and check out the leak suspects.

Try profiling the application to see which part of the code is responsible for the BitMatrix allocation, try to track it back into the application code.

The fact that the CaptureActivity example experiences the same issue may be caused by a wrong use of the library, so it does not necessarily proves that the lib is leaking memory. For example, the library could have been updated while the example was left the same.

他のヒント

I found the same problem (in version 2.3 of ZXing) running on the Android emulator (Intel version). The root cause appeared to be the following: In method selectBestPatterns of class FinderPatternFinder, a NotFoundException is thrown when no valid (QR) finder pattern was found. This exception is caught in method decodeInternal of class MultiFormatReader. This exception thus skips the normal return of a few method invocations. I have found that due to this "exceptional return" the instance of FinderPatternFinder is not released, and that instance in turn holds on to a reference of BitMatrix, that uses quite some memory. Sounds crazy, and I don't think this is according to the Java spec, so I call it a bug in the emulator. The workaround is to not rely on an exception to signal that the finder pattern was not found. I did it by returning a few null results while winding down the stack of method invocations. This completely solved the memory leak.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top