0

我们在 Play 商店中有几个应用程序。作为对新 Lollipop 版本的准备测试,我想看看我们的应用程序的位置。

我采用的第一种方法是使用三星 Google 版 S4,并告诉它使用 ART 运行时环境启用和重启(也可在我们的 Nexus 5 上使用)。这启发了我一些问题,当这是 Nexus 9 正式发布时,我可以解决这些问题。

然而,随后发布了一个将 Lollipop 5.0 推送到 Nexus 7 的版本。将它推送到那里给我带来了其他问题。但是,打印输出似乎仍然与 ART 有关。如:

11-03 09:22:29.419: E/art(6256): Tried to mark 0xfe80a920 not contained by any spaces
11-03 09:22:29.419: E/art(6256): Attempting see if it's a bad root
11-03 09:22:29.420: A/art(6256): art/runtime/gc/collector/mark_sweep.cc:381] Can't mark invalid object

随后发生崩溃。

你们有没有发现 ART 的某些功能与 5.0+ 的交互方式与 5.0 之前的交互方式不同?也许对导致这种情况的最近的操作系统有更严格的要求。

在发布之前,我没有使用过这些可下载的版本。与即将发布的实际版本相比,它们是否可靠?

更新

该问题已得到解决,并且确实与从本机代码中滥用某些方法调用到 java 对象的方式有关。因为我能够解决需要甚至首先进行这些调用的问题,所以我只是在这个特定的本机代码段上删除了这个代码段,而是用 Java 代替。

在本机代码中似乎不是问题,因为断点是在本机代码之后收到的,但显然在稍后的某个时间点,它在稍后的给定时间点导致了一些未确定的崩溃。也许只是通过与 Dalvik 相比,ART 的工作方式的设计。

4

1 回答 1

0

如果您使用的是本机 C/C# 代码,请检查是否使用 GetArrayElements 和 ReleaseArrayElements 并将其替换为:GetArrayRegion:

当您想要做的只是将数据复制入或复制出时,有一个替代调用(如 GetArrayElements 和 GetStringChars)可能非常有用。考虑以下:

jbyte* data = env->GetByteArrayElements(array, NULL);
if (data != NULL) {
    memcpy(buffer, data, len);
    env->ReleaseByteArrayElements(array, data, JNI_ABORT);
} This grabs the array, copies the first len byte elements out of it, and then releases the array. Depending upon the implementation,

Get 调用将固定或复制数组内容。代码复制数据(可能是第二次),然后调用 Release;在这种情况下,JNI_ABORT 确保没有第三个副本的机会。

可以更简单地完成同样的事情:

env->GetByteArrayRegion(array, 0, len, buffer); This has several advantages:

需要一个 JNI 调用而不是 2 个,从而减少开销。不需要固定或额外的数据副本。降低程序员出错的风险——没有在失败后忘记调用 Release 的风险。同样,您可以使用 SetArrayRegion 调用将数据复制到数组中,并使用 GetStringRegion 或 GetStringUTFRegion 从字符串中复制字符。

更多信息:http: //developer.android.com/training/articles/perf-jni.html#region_calls

于 2014-11-03T23:23:11.850 回答