【问题标题】:Is there a memory leak in the Android ZXing library?Android ZXing 库是否存在内存泄漏?
【发布时间】:2013-05-31 13:39:31
【问题描述】:

我使用 ZXing 库编写了一个 Android 应用程序,我得到了一个java.lang.OutOfMemoryError

首先,我确定错误就在我身上,因此我使用了 Patrick Dubroy Google I/O 2011: Memory management for Android Apps 和其他几个关于如何追踪内存泄漏的教程(如 Android Memory Leaks OR Different Ways to Leak)的 Eclipse 内存分析器 (MAT)。

在 MAT 中,我发现随着时间的推移,数百个 com.google.zxing.common.BitMatrix 实例占用了我的大部分堆内存。

令人惊讶的是,我在原来的ZXing测试程序“CaptureActivity”中遇到了同样的问题!

经过一番调查,我发现DecodeHandler 类中的活动引用可能会阻止垃圾收集器释放BitMatrix。但我的经验太少,无法验证这一点。此外,我很惊讶在原来的 ZXing 库(2.1 版)中发现了这个问题。

任何人都可以重现或曾经经历过这种现象吗?

【问题讨论】:

  • 我从未见过内存泄漏的证据,也想不出一个可以保存引用的地方。它从哪里显示这些是从哪里引用的?
  • 这与这个问题有什么关系?

标签: android memory-leaks garbage-collection zxing eclipse-memory-analyzer


【解决方案1】:

我在 Android 模拟器(Intel 版本)上发现了同样的问题(在 ZXing 2.3 版本中)。根本原因似乎如下: 在FinderPatternFinder 类的方法selectBestPatterns 中,当没有找到有效的(QR)查找器模式时,会抛出NotFoundException。此异常在类MultiFormatReader 的方法decodeInternal 中被捕获。因此,此异常跳过了一些方法调用的正常返回。我发现由于这个“异常返回”,FinderPatternFinder 的实例没有被释放,而该实例又保留了BitMatrix 的引用,这使用了相当多的内存。 听起来很疯狂,而且我认为这不符合 Java 规范,所以我称之为模拟器中的错误。 解决方法是不依赖异常来表示未找到查找器模式。我通过在结束方法调用堆栈的同时返回一些空结果来做到这一点。这样就彻底解决了内存泄漏问题。

【讨论】:

  • 好吧,如果属实,那确实是 JVM 实现中的一个错误。控制流完全没问题,与垃圾收集无关。这些元素离开帧堆栈;你认为他们在哪里举行?如果其中任何一个属实,则更有可能是模拟的 JVM GC 无法跟上处理帧的速度并声明 OOM 只是因为它的线程花费了太长时间。
  • @SeanOwen:模拟的 JVM 非常快,因为它以快速虚拟模式运行英特尔代码。我使用 MAT 来查找持有堆栈外元素的内容。它展示了元素,但没有展示它们的元素。您可以在 LogCat 中看到使用的内存如何不断增长,直到达到限制。
【解决方案2】:

我认为你在正确的轨道上。您需要继续查看 MAT 堆配置文件,以确定用户代码的哪一部分持有对 DecodeHandler 的引用并传递到 BitMatrix。尝试遵循来自BitMatric 的传入引用,计算支配树并检查泄漏嫌疑人。

尝试分析应用程序以查看代码的哪一部分负责分配BitMatrix,尝试将其跟踪回应用程序代码中。

CaptureActivity 示例遇到同样的问题,可能是由于库的使用不当造成的,因此并不一定证明该库有内存泄漏。例如,库可能已经更新,而示例保持不变。

【讨论】:

    猜你喜欢
    • 2011-10-22
    • 2011-01-29
    • 2011-05-08
    • 1970-01-01
    • 2011-06-26
    • 2011-10-07
    • 1970-01-01
    • 1970-01-01
    • 2012-09-13
    相关资源
    最近更新 更多