如何从命令行设置 android 仪器测试的 vm heapsize

Posted

技术标签:

【中文标题】如何从命令行设置 android 仪器测试的 vm heapsize【英文标题】:How to set the vm heapsize of android instrumentation tests from command line 【发布时间】:2021-05-26 03:20:49 【问题描述】:

我正在模拟器上的 androidJunitRunner 上运行测试。

这是 ci 运行的一部分

模拟器是使用以下命令创建的:

回声不 | avdmanager create avd -n android29 -k 'system-images;android-29;default;x86' --force

模拟器 -gpu swiftshader_indirect -no-window -feature GLESDynamicVersion -avd android29 -memory 3072 -partition-size 2048 -cache-size 2048 >/dev/null 2>&1 &

我收到错误:

java.lang.OutOfMemoryError:无法分配 9437192 字节分配,4724576 空闲字节和 4613KB 直到 OOM,目标占用空间 16777216,增长限制 16777216

看起来 junit runner 的堆大小是 16MB。为什么是这样 ?我该如何控制这个?我在谷歌上搜索了几个小时,但找不到可以定义堆大小的位置。

【问题讨论】:

【参考方案1】:

更新:下面的这个答案可能不正确。最重要的开关是-memory 但在android emulator 29中有576MB的上限:https://androidstudio.googleblog.com/2019/08/emulator-2919-canary.html?hl=th

我很乐意找到解释此堆计算的来源。

旧答案: 我找到了办法。

.android 下有一个配置文件,其中包含堆大小。它可以很容易地被操纵。

我将其作为 github 操作的一部分进行操作:

 async function fixIni(version, sizeInMb)
const homedir = require('os').homedir();
    const path = `$homedir/.android/avd/android$version.avd/config.ini`
    const content = await fs.promises.readFile(path, "utf8")
    const fixed = content.split("\n").map(line => line.startsWith("vm.heapSize=")? `vm.heapSize=$sizeInMbM`: line)
    await fs.promises.writeFile(path,fixed.join("\n"))

这必须在 avdmanager 创建 avd 之后和模拟器启动之前运行

【讨论】:

这项工作是否为您修复了仪器测试?我收到类似的错误,但该行的末尾显示VmSize 1151480 kB,我在想如果它已经是 1124 MB,为什么增长限制只有 16MB,如果这个选项改变了这一点。 这是一个偶发错误,我需要更多时间部署修复程序才能得到明确的答案。我想我至少还需要 2 周。模拟器的内存和每个进程的堆大小是有区别的。我用 dumpsys 验证了仪表内存大小增长到我想要的但让我们看看是否不会有任何错误 啊,你是对的。 VmSize 与 VM 堆大小不同。我发现无论我如何调整 vm.heapSize 值,我都无法获得超过 576MB 的堆大小。不过,我使用的是 Nexus 5X 硬件配置文件。再说一次,与 16 MB 相比,这应该是很大的改进:) 如果再次发生这种情况,请分享。我也会分享一些发现! 这似乎对我不起作用。系统服务器最终还是崩溃了,奇怪的是它的增长限制仍然是 16 MB。 @AfzalN 我发现这个有趣的阅读 rainforest.engineering/2021-04-16-android-heap-race 它帮助我绕开了我的问题

以上是关于如何从命令行设置 android 仪器测试的 vm heapsize的主要内容,如果未能解决你的问题,请参考以下文章

Android Studio 单元测试配置

仪器命令行工具出错

仪器无法从命令行启动

从设备上的命令行运行仪器 4.5 时无法启动跟踪

如何设置凭据以从 GCE VM 命令行使用 Gmail API?

使用 Gradle 运行特定的 Android 仪器测试