为了账号安全,请及时绑定邮箱和手机立即绑定

Java (Android 8.0.0) 中的本地浮点变量如何被损坏?

Java (Android 8.0.0) 中的本地浮点变量如何被损坏?

HUH函数 2023-09-13 15:24:31
更新了重要的新信息(见底部)编辑了更好的日志代码我正在追踪我们的应用程序中的一些图形损坏,并将其追溯到这个函数(我已经在其中大量记录了日志):public final int p_PostDraw(){    bb_std_lang.print("Dissolve encountered.");    float t_d=c_GColour.m_dissolve;    bb_std_lang.print("Cached dissolve value locally: "+c_GColour.m_dissolve+ " " + t_d);    c_GColour.m_dissolve=c_Gel.m_colstack.p_Top().m_a;    bb_std_lang.print("Updated dissolve value: " + c_GColour.m_dissolve);    c_Gel.m_colstack.p_Top().m_a=1.0f;    bb_std_lang.print("Monitoring t_d="+t_d);    super.p_PostDraw();    bb_std_lang.print("Monitoring t_d="+t_d);    c_GColour.m_dissolve=t_d;    bb_std_lang.print("Dissolve post restore " + c_GColour.m_dissolve);    return 0;}大多数情况下,这会按预期工作,但在游戏中的某个时刻,会记录以下内容:09-30 14:40:59.086 10545-11101/? I/[Monkey]: Dissolve encountered.09-30 14:40:59.086 10545-11101/? I/[Monkey]: Cached dissolve value locally: 1.0 1.009-30 14:40:59.086 10545-11101/? I/[Monkey]: Updated dissolve value: 0.109-30 14:40:59.086 10545-11101/? I/[Monkey]: Monitoring t_d=1.009-30 14:40:59.087 10545-11101/? I/[Monkey]: Monitoring t_d=-1.6314132E-1909-30 14:40:59.087 10545-11101/? I/[Monkey]: Dissolve post restore -1.6314132E-19为您分解一下:静态值m_dissolve被复制到局部变量t_d中,并且值为 1.0f。然后将静态值修改为 0.1f 并用于子对象的渲染。完成后,局部变量t_d在用于恢复静态值之前再次被记录,但同时神秘地变成 -1.6314132E-19 (这个值每次似乎都不可预测地不同)。我不知道本地 Java 变量会以这种方式被破坏。
查看完整描述

3 回答

?
慕森卡

TA贡献1806条经验 获得超8个赞

我在使用 LibGDX 发布的游戏中也遇到了这个问题,就像 tscissors 一样。

经过几个月的调试,现在我确信我遇到的问题与被破坏的浮点变量有关,就像这篇文章中所描述的那样。

对我来说,一个简单的解决方法很有帮助:在AndroidManifest.xml设置属性时成功android:vmSafeMode消除 true了错误,因为它禁用了 JIT 优化。

参见安卓说明:

android:vmSafeMode

指示应用程序是否希望虚拟机 (VM) 在安全模式下运行。默认值为“假”。此属性是在 API 级别 8 中添加的,其中“true”值会禁用 Dalvik 即时 (JIT) 编译器。

此属性在 API 级别 22 中进行了调整,其中“true”值禁用 ART 提前 (AOT) 编译器。


查看完整回答
反对 回复 2023-09-13
?
MMMHUHU

TA贡献1834条经验 获得超8个赞

这是一个非常奇怪的问题,似乎是 ART/JIT 中的错误。我可以看到至少 3 个不同的开发者故事都遇到同样的问题。我认为可能会有更多,但这个错误确实很难重现。

我在使用 LibGDX 框架开发游戏时遇到了这个问题。该框架中的 UI 是通过大量复杂的计算创建的,并且在那里大量使用了浮点数。在我的例子中,UI 组件收到了错误的坐标,因此布局完全被破坏。

奇怪的是,您无法使用 DEBUG apk 重现此问题,只能使用 RELEASE apk 重现。更改清单的值android:debuggable=true也不起作用。所以调试真的很痛苦,你需要监控logcat并验证float变量的值。

解决方法

在我真正需要 UI 相关方法之前,我强制编译器对它们执行“去优化”。我创建了模拟“Table”组件,用其他模拟组件填充它(创建类似于真实组件的布局),并调用我在日志中看到的方法(当去优化发生时)。我每次在应用程序启动时都会进行此操作,并且问题似乎对我来说已“修复” - 此后“去优化”永远不会发生,并且在此之后布局始终正确。

我希望它能帮助那些在这个问题上花费了大量时间的人。


查看完整回答
反对 回复 2023-09-13
?
哈士奇WWW

TA贡献1799条经验 获得超6个赞

我不知道本地 Java 变量会以这种方式被破坏。

如果某处的某些本机代码破坏了包含该变量的堆栈帧,则可能会发生这种情况t_d

如果本节中存在竞争条件或内存危险,也可能会发生这种情况:

   float t_d=c_GColour.m_dissolve;
   bb_std_lang.print("Dissolve pre stack: " + c_GColour.m_dissolve);

如果你仔细观察,你实际上并没有打印t_dc_GColour.m_dissolve您正在做的是在将...分配给打印 ... 的(表观)值t_d。它可能已经改变了。

(请注意,您正在访问一个裸变量m_dissolve,显然没有任何同步。即使声明为 ,这里也存在潜在的竞争条件m_disolvevolatile


查看完整回答
反对 回复 2023-09-13
  • 3 回答
  • 0 关注
  • 70 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信