了解Android的紧凑循环/旋涂暂停错误 [英] Understanding Android Tight loops / Spin-On-Suspend error

查看:167
本文介绍了了解Android的紧凑循环/旋涂暂停错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Android上开发游戏,太空RPG - 目前只看到这个错误弹出在大多数银河S4S,和HTC的。这是所有Java。

本场比赛将停止,当我尝试调试过程,并暂停有问题的线程,它不会暂停,和旋涂暂停发生错误。 线程转储让我看看,这是里面一定while循环走的是一条希望结束位置和向后遍历在不断增加距离的步骤,找到一个起始位置。

这就是事情烦。我可以验证回路不能无限期地运行,即使条件为,而(真),这是不可能为它多跑,也许200次迭代之前,我的突破被调用(这个说法被备份的code工作所有其他的手机我都试过)上。

要帮助减轻我心中的这件事,我加入了循环中简单的加变量,如果它必须高于1000它将记录一些东西,所以我可以看到,它没有运行过很多次,以防万一有些变量设置不好什么的。 当这个计数器code是present,NO崩溃/挂起发生。我也不看不到任何记录表明它跑了超过1000次。

如果我删除此计数器,挂起发生5-10秒的上场后,每次[其中,while循环将有可能运行10次,尽管这改变。

我的提问因此,这到底是怎么回事? :P 为什么这些新的手机(不过貌似没有旧手机)有一个循环,做有效的工作,持续时间不长,出现问题时,有没有递增的变量在那里。怎么可能线程可能拖延该循环,以及如何有一个额外的计数器变量解决这个问题? 这项工作正在做对了OpenGL渲染线程,如果这是非常重要的。

我有这样的情况发生在大多数S4S的报道,但至少有一个S4在那里它并没有发生。我使用的今天,它正在发生的事情之一。这使我怀疑它可能是做了具体的Andr​​oid,JAVA,Dalvik的或别的东西在手机上,但我遗憾的是不要有从那里工作的S4任何细节。

任何帮助,指导,思想进一步阅读的东西一样,这将是AP preciated,非常感谢。

 浮法VEL = 1.0F; //最终速度为1。我们正在往回走,找到了什么样的起始速度将需要。
INT I = 0;
双XMATH = Math.sin(腐*(Math.PI / 180.0f)); //速度为x的分量,Y方向的基础上旋转
双ymath = Math.cos(腐*(Math.PI / 180.0f));
而(真){
        / *本节注释掉,摊主从未发生过...
         ++我;
        如果(ⅰ> 1000){
            //东西去了,而错
            VEL = 91.0f; // LOG在这里,现在有一个备用的值justincase
            打破;
        }
        * /
        VEL * = 1.2F;
        DX  -  = VEL * XMATH;
        DY + = VEL * ymath;
        如果(距离≤(浮动)的Math.sqrt(DX * DX + DY * DY)){
            打破;
        }
}
//给这个船的速度是适合剩余的距离
_AI.Ship.Velocity = VEL;
 

解决方案

这可能是 http://b.android .COM / 58726

该错误已全部细节;总之:一些供应商出现使用Dalvik虚拟机的一个修改的版本。从在某些情况下发生的JIT编译器prevent线程挂起的更改。

的试金石这个问题的标准零售设备对纯粹的Andr​​oid的谷歌播放版的GS4和HTC1的。如果是前者显示了断的行为,但后者工作正常,你可能会看到一个供应商特定的问题。

解决方法就是做你做了什么:让code少,因此它不会落入优化的情况下,有效的。理想情况下,应用程序将运行时选择没有问题,设备具有不同的code路径,但我不知道检测的问题在运行时的好办法。

I am developing a game on android, 'Space RPG' - currently only seeing this error pop up on most Galaxy S4s, and HTC Ones. This is all Java.

The game will stall, when I try to debug the process and suspend the thread in question, it won't suspend, and a spin-on-suspend error happens. The thread dump lets me see that it was inside a certain while loop that is taking a desired 'end position' and iterating backwards at an ever increasing distance step to find a 'start position'.

This is where things get annoying. I can verify that the loop can not run indefinitely, even though the condition is while(true), it is not possible for it to run more than maybe 200 iterations before my break gets called (this assertion being backed up by the code working on every other phone I have tried).

To help ease my mind on this matter, I added a simple incremented variable inside the loop, and if it ever goes above 1000 it will log something out so I can see that it DID run too many times, just in case some variable was set badly or something. When this counter code is present, NO crash/hang occurs. Nor do I see any logs indicating it ran over 1000 times.

If I remove this counter, the hang occurs every time after 5-10 seconds of playing [in which the while loop will have run maybe 10 times, though that varies].

My question is therefore, what the hell is going on? :P Why would these newer phones (but seemingly none of the older phones) have a problem with a loop that is doing valid work and doesn't last long, when there is no incremented variable in there. How could the thread possibly stall in that loop, and how does having an extra counter variable fix the issue? This work is being done on the opengl render thread, in case that is important.

I have reports of this happening on most S4s, but there is at least one S4 out there where it didn't happen. The one I am using today it IS happening. This makes me wonder if it could possibly be to do with the specific android, java, dalvik or something else on the phone but I unfortunately dont have any details from the S4 where it worked.

Any help, guidance, thoughts or further reading on stuff like this would be appreciated, thanks a lot.

float vel = 1.0f; // final velocity is 1. We are working backwards to find out what the starting velocity will need to be.
int i = 0;
double xmath = Math.sin(rot* (Math.PI/180.0f)); // component of velocity for x,y direction based on rotation
double ymath =  Math.cos(rot* (Math.PI/180.0f));
while (true) {
        /* with this section uncommented, the stall never happens...
         ++i;
        if (i>1000) {
            // Something went rather wrong
            vel = 91.0f; // LOG WAS HERE, now has a fallback value justincase
            break;
        }
        */
        vel *= 1.2f;            
        dx -= vel* xmath;
        dy += vel* ymath;           
        if (distance < (float)Math.sqrt(dx*dx+dy*dy)) {
            break;
        }
}
// Give the ship a velocity that is appropriate for the distance remaining
_AI.Ship.Velocity = vel;

解决方案

This is probably http://b.android.com/58726.

The bug has full details; in short: some vendors appear to use a modified version of the Dalvik VM. Changes made to the JIT compiler prevent thread suspension from occurring in certain situations.

The litmus test for this issue is to compare the standard retail device against the "pure Android" Google Play Edition of the GS4 and HTC1. If the former shows the broken behavior, but the latter works correctly, you are likely seeing a vendor-specific problem.

The workaround is to do what you've done: make the code less efficient so it doesn't fall into the "optimized" case. Ideally the app would runtime-select a different code path for devices without the issue, but I don't know of a good way to detect the problem at run time.

这篇关于了解Android的紧凑循环/旋涂暂停错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆