如何分析Dalvik GC行为?

5
我正在开发一个Android应用程序。它是一个长时间运行的应用程序,不断处理传感器数据。在运行应用程序时,我在logcat中看到很多GC消息,大约每秒钟一次。
这很可能是因为在循环中创建并立即取消引用对象。
如何找出哪些对象被创建并立即释放?
我尝试过所有Java堆分析工具(*),它们都关注堆中对象的计数和大小。虽然它们很有用,但我更想知道创建临时短生命周期对象的地方。
(*)我尝试过jcat和Eclipse MAT。我无法在Android堆转储上使用hat;它抱怨不支持的转储文件版本。
2个回答

4
我如何找到立即创建和释放的对象?
步骤1:暂时修改您的代码(或创建一个包含相关代码部分的碎片项目),其中您可以单击按钮或其他内容运行传感器处理逻辑一次。
步骤2:进入DDMS(独立或Eclipse视图)。
步骤3:选择您的模拟器,然后单击Allocation Tracker选项卡。
步骤4:将应用程序置于等待来自步骤#1的按钮单击的状态,然后在DDMS Allocation Tracker选项卡上单击Start Tracking。
步骤5:单击按钮,并在传感器处理过程完成后,在DDMS Allocation Tracker选项卡上单击Get Allocations。
这将告诉您在代码的那部分中分配了什么。它并不告诉您什么被“释放”,因为在GC周期运行之前是无法确定的。
我不确定,但是android.os.Debug类中的startAllocCounting()可能具有与单击“开始跟踪”按钮相同的效果。如果是这样,您可以简单地为您的循环仅跟踪一次分配而不是搞乱上面概述的代码更改。另外,这里有一篇关于DDMS和分配跟踪的简短技术文章

1
双重发布:\为什么不在不更改代码的情况下运行分配跟踪器?(至少第一次) - Pedro Loureiro
1
@Pedro Loureiro:首先,你会在问题循环之外得到大量的分配,而分配列表可能会变得非常长。其次,循环本身可能会使列表难以管理。将有关代码段的一次遍历隔离出来将使数据最易于理解。然而,你的评论提醒了我一些事情,我马上会添加到我的答案中... - CommonsWare
感谢指向Allocation Tracker的指针。我完全错过了它。顺便说一下,文档说它在Eclipse集成(ADT)中不可用。 - HRJ
1
@HRJ:这是可能的——我不使用Eclipse。然而,最近工具经历了一轮相当重大的修订,所以你可能需要再次检查以确保这不是文档错误。请注意,如果是正确的,你将需要在使用独立DDMS时关闭Eclipse,因为据我所知,你不能同时运行两个DDMS。 - CommonsWare

1

啊,谢谢!我错过了分配跟踪器,因为它显然不在 Eclipse 集成中可用。 - HRJ
1
现在是,只是为了记录 :) - manmal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接