为什么Android ART在离开其范围时有时会赢得GC局部变量?

时间:2016-10-28 04:05:22

标签: android variables memory garbage-collection local

在我看来,有时ART会在离开范围时出现GC局部变量,但有时它不会发生。在我看来,它总是会发生在Dalvik。

我已使用Android Studio内存监视器运行以下测试用例。他们全都是关于在onCreate中添加的方法testMemoryUsage:

@Override
protected final void onCreate(final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    testMemoryUsage(); // For testing only
    setupActivity(); // Added to setup the activity to be ready to run
}

测试用例1(控制)

testMemoryUsage只是一个空方法:

// For testing only
private void testMemoryUsage() {
}

测试用例2(非最终局部变量)

testMemoryUsage只创建一个非最终局部变量uniqueStrings:

// For testing only
private void testMemoryUsage() {
    List<String> uniqueStrings = new Vector<>();
    for (Integer index = 0; index < 1000000; index++) {
        uniqueStrings.add(index.toString());
    }
}

测试流程

大约每10秒钟,按下设备后退按钮关闭应用程序,然后通过单击应用程序图标立即重新打开。

测试设备

GT-N7000(Android版本4.1.2) - Dalvik

LG-​​D802(Android版本4.4.2) - Dalvik

LG-​​H860(Android版本6.0.1) - ART

Nexus 5X(Android 7.0版) - ART

通过使用2个设备,每个设备具有不同的Android版本,使用Dalvik和2个设备,每个设备都具有不同的Android版本,使用ART,此设置应该消除由于设备和Android版本而不是Dalvik和ART的变量。

内存监控结果

Memory Monitor Result 1(LG-H860 in Test Case 1)

Nexus 5X(ART)显示与控制测试用例基本相似的内存监控结果。 然而,GT-N7000(Dalvik)和LG-D802(Dalvik)的结果几乎持平。

Memory Monitor Result 2(LG-H860 in Test Case 2)

Nexus 5X(ART)显示了基本相似的内存监视器结果。 然而,GT-N7000(Dalvik)和LG-D802(Dalvik)都显示锯齿状结果,在完成添加所有1000000个唯一字符串后触发下降边缘,这意味着Dalvik总是立即GC将局部变量uniqueStrings on保留范围testMemoryUsage。

在ART的情况下,它有时会将GC作为局部变量uniqueStrings在第一次和第二次应用程序启动时离开其范围testMemoryUsage,但有时它不会。此外,有时这样的GC会在随后的关闭和重新开放时发生,但有时会这样做。

我已经在LG-H860(ART)和Nexus 5X(ART)上进行了近10次这些测试,并且内存监视器结果非常不一致(上述&#34;有时&#34;)即使是在相同的测试设备上进行相同的测试,除了1点 - GC将立即在上述时间发生,或者无论我等待多久都不会发生,尽管如果我可能会发生在应用程序内做其他事情。 然而,GT-N7000(Dalvik)和LG-D802(Dalvik)的内存监控结果非常一致。

我试图在互联网上搜索答案,但尽管付出了很多努力,但我找不到任何东西,所以我决定在这里问:

ART真的是所有这些问题的根源,还是我犯了一些可怕的错误?

1 个答案:

答案 0 :(得分:1)

ART的GC算法与Dalvik的GC算法不同。一旦应用程序退出,Dalvik就会被触发,甚至在应用程序运行时会多次触发,导致由于操作被阻止导致UI线程暂停。在你的到期中,Dalvik的行为是完美的,它会在应用程序退出后立即触发并执行并发GC扫描以清除内存。

ART的默认计划是CMS(并发标记清除)计划,该计划主要使用粘性CMS和部分CMS。 Sticky CMS是ART的不动的世代垃圾收集器。它仅扫描自上一次GC以来修改的堆部分,并且只能回收自上次GC以来分配的对象。除了CMS计划之外,当应用程序将进程状态更改为不易察觉的进程状态(例如,后台或缓存)时,ART会执行堆压缩。所以你看到ART的GC行为是完美的,它等待下一个GC扫描周期来清除内存。这有两个方面:

  1. 没有异步GC扫描。因此,与Dalvik相比,GC扫描的数量减少了。
  2. 在您的情况下,由于应用程序会立即重新启动,因此可以正确地重用内存。
  3. 因此,ART不是所有这些问题的根源,但它的表现方式与它的设计相同。

    您将获得更详细的信息here