【发布时间】:2016-02-26 02:15:48
【问题描述】:
在 Android Studio 中开发 Android 应用时,while 循环中使用的变量的值不正确。我将它在一个测试用例中简化为一个非常简单的用例:
- 在 Android Studio 中新建项目,空白 Activity
- 将以下代码添加到主活动中
方法开始:
@Override
public void onStart() {
super.onStart();
int count = 2;
int index = 1;
int value = 23;
Log.i("test", "value before = " + value);
while (index < count) {
Log.i("test", "value in while loop = " + value);
index++;
value = 0;
}
}
执行测试应用时的输出是:
value before = 23
value in while loop = 0
而结果应该是
value in while loop = 23
调试时,结果如预期('while loop = 23'),但在常规调试构建中,结果是错误的。主活动类的反汇编代码看起来没问题,变量'value'的值在while循环体的末尾设置为0。当 while 循环体中的某些代码或函数使用变量 'value' 时,它的值将是 0 而不是 23。在测试用例中,我使用 Log 语句来简化。
换行不会出错
value = 0;
到
if (value == 23) {
value = 0;
}
或者当我删除线时
value = 0;
所以它看起来像一些优化错误。但是做了哪些优化会导致这种情况呢?它使代码不可靠。
【问题讨论】:
-
这真的取决于您的特定 Java 版本和 - 最重要的是 - 特定的 JVM。但是,是的,Java 进行优化,JVM 进行运行时优化,循环展开可以是优化之一。例如,看这里:Java JIT loop unrolling policy?.
-
@paulsm4 将代码输出从 23 更改为 0 是一种非法优化。需要发生的事情已明确定义。您可以在纸上追踪代码,您会发现 23 是您可以在此处打印的唯一值。只有在没有明显影响的情况下才允许重新排序指令。
-
Idk,但我以前见过这个,只在三星 Galaxy S5s 左右。没有其他设备受到影响。我猜三星搞砸了他们的优化。我没有时间进一步调查,因为我没有那种类型的手机可以测试(只有几个 Play 商店错误报告)
-
@joshgoldeneagle 我检查了 for 循环,它有同样的问题。有变通办法,这不是问题。但问题是这个问题正在损害正常的执行流程,这非常危险,因为你没有预料到。
-
感谢所有 cmets。以@zapl 为例,可以确认存在真正的优化错误,至少在某些三星手机中是这样。在执行优化时,绝不应该以更改代码语义的方式更改执行流程。 如果有人知道如何与三星联系,请告诉我。
标签: java android optimization runtime-error samsung-mobile