我在Android5.x Camera2 API中发现了内存泄漏,我也已报告。问题是当您使用Android设备时,它的Camera2 API是在LEGACY模式下实现的。在这样的设备上,调用context.getSystemService(Context.CAMERA_SERVICE)会导致context被保留,这样就不会被垃圾收集。
如果此context是多次启动的活动,则可能会挂起对数十个从未垃圾收集的活动实例的引用。
这一问题似乎只发生在具有Camera2 API以LEGACY模式实现的Lollipop设备上(例如HTC M8、三星Galaxy S4),而在以FULL模式实现Camera2 API的三星Galaxy上则没有发生这种情况。
为了演示这个问题,我创建了一个小型演示应用程序。应用程序包含两个活动:第一个活动包含一个按钮,该按钮调用第二个活动。第二个活动获得CameraManager,并查询对第一个背向照相机的Camera2 API支持级别,并将结果返回给第一个活动。如果在以Camera2模式实现LEGACY API的设备上运行应用程序,在按下按钮98次后,导致GC,然后转储HPROF,您将看到Main2Activity的98个活动实例,如这个http://www.pohrani.com/f/1H/gs/4EFlHKoj/sgs4.png。
如果在以Camera2模式实现FULL API的设备上执行相同的操作,您将看到Main2Activity的0个活动实例,如下面的http://www.pohrani.com/f/2q/bV/4srUZIJL/sgs6.png
有办法解决这个漏洞吗?
有人可能会问我为什么要这么做?在我们公司,我们正在开发条形码和OCR扫描解决方案和一个著名的PhotoMath应用程序。因此,我们有一个扫描活动,控制相机和扫描过程。在启动时,活动检查设备是否在FULL或LIMITED模式下支持Camera2 API,并尝试使用它以获得更好的性能,而如果Camera2 API处于LEGACY模式,那么我们更喜欢使用旧的Camera2进行相机管理,就像我们在前棒棒糖设备上所做的那样。
由于上述内存泄漏,每当将我们的SDK集成到其应用程序中的客户端启动扫描活动、执行扫描并获得结果时,就会因为错误而泄漏一个扫描活动实例。如果客户端扫描很多,这会占用超过20 MB的内存-一个严重的问题!
因此,如果有人知道如何解决这个问题,我将永远感激!
发布于 2015-08-11 13:57:51
有办法解决这个漏洞吗?
您可以在getSystemService()单例上调用Application。因此,与其:
getSystemService(CAMERA_SERVICE)你可以使用:
getApplicationContext().getSystemService(CAMERA_SERVICE)如果您的评估是正确的,那么这将导致这些额外的引用是对现有的Application单例的引用,这在您的过程中总是存在的。它实际上是“预泄漏”,你不能通过更多地引用它来进一步泄露它。
发布于 2015-08-11 23:52:33
这是一个在L MR1中修复的Android错误。
基本上,CameraManager保留了对其创建的上下文的引用,然后连接到照相机服务。此连接使相机管理器实例无限期地保持活动,因此也使上下文无限期地保持活动。
在L MR1中,这是固定的,以便在不再引用时正确地允许回收CameraManager对象。
https://stackoverflow.com/questions/31943514
复制相似问题