Android ';方法超出编译器指令限制';64K方法下井上的信息
我经常在我的日志中看到这样的重复消息:Android ';方法超出编译器指令限制';64K方法下井上的信息,android,methods,limit,Android,Methods,Limit,我经常在我的日志中看到这样的重复消息: Method exceeds compiler instruction limit: 29278 in void com.xxxxxxapp.xxxxxx.MyGLRenderer.onDrawFrame(javax.microedition.khronos.opengles.GL10) Method exceeds compiler instruction limit: 29278 in void com.xxxxxxapp.xxxxxx.MyGLRen
Method exceeds compiler instruction limit: 29278 in void com.xxxxxxapp.xxxxxx.MyGLRenderer.onDrawFrame(javax.microedition.khronos.opengles.GL10)
Method exceeds compiler instruction limit: 29278 in void com.xxxxxxapp.xxxxxx.MyGLRenderer.onDrawFrame(javax.microedition.khronos.opengles.GL10)
Method exceeds compiler instruction limit: 29278 in void com.xxxxxxapp.xxxxxx.MyGLRenderer.onDrawFrame(javax.microedition.khronos.opengles.GL10)
分解代码通常会以较小的数字显示相同的消息:
Method exceeds compiler instruction limit: 22400 in void com.xxxxxxapp.xxxxxx.MyGLRenderer.onDrawFrame(javax.microedition.khronos.opengles.GL10)
我以为64000是个神奇的数字。我的游戏代码似乎总是运行良好,尽管有这样的唠叨消息,而且它不仅仅是在opengl onDrawFrame方法中。我在64K以下的更新方法中得到了类似的消息,尽管更新代码比绘图代码更容易分解
搜索“方法超过编译器指令限制”刚得到链接到可怕的“Dalvik编译器限制64K方法”错误。我必须一直忽略这个吗?发生这种情况是因为
编译器::iPathLogicalCase
:
跳过病理性大方法的编译-通过指令计数或num vregs
Dalvik使用16位UINT进行指令和寄存器计数。我们将限制为四分之一,这也保证了我们不能溢出16位内部Quick SSA名称空间
来源:
16位uint
可以表示最大值65535
,除以4
,等于16383.75
将目标级别从Dalvik
提高到ART
可能会绕过它;由于指令计数,Dalvik和似乎不兼容
之后将检查寄存器计数,因此这似乎不是问题所在
修补compiler.cc
也是一个选项,尽管不是一个好选项
- 当
为4
时,这将允许双倍的金额2
- 当not
也应继续编译返回true时
if (accessor.InsnsSizeInCodeUnits() >= UINT16_MAX / 4) {
LOG(INFO) << "Method exceeds compiler instruction limit: "
<< accessor.InsnsSizeInCodeUnits()
<< " in " << dex_file.PrettyMethod(method_idx);
return true;
}
if(accessor.InsnsSizeInCodeUnits()>=UINT16\u MAX/4){
日志(信息)发生这种情况的原因是编译器::IsPathologicalCase
:
跳过病理性大方法的编译-通过指令计数或num vregs
Dalvik使用16位UINT进行指令和寄存器计数。我们将限制为其中的四分之一,这也保证了我们不能溢出16位内部Quick SSA名称空间
来源:
16位uint
可以表示最大值65535
,除以4
,等于16383.75
将目标级别从Dalvik
提高到ART
可能会绕过它;因为Dalvik
并且由于指令计数而看起来不兼容
之后将检查寄存器计数,因此这似乎不是问题所在
修补compiler.cc
也是一个选项,尽管不是一个好选项
- 当
4
为2
时,这将允许双倍的金额
- 当not
返回true时
也应继续编译
这是有故障的检查:
if (accessor.InsnsSizeInCodeUnits() >= UINT16_MAX / 4) {
LOG(INFO) << "Method exceeds compiler instruction limit: "
<< accessor.InsnsSizeInCodeUnits()
<< " in " << dex_file.PrettyMethod(method_idx);
return true;
}
if(accessor.InsnsSizeInCodeUnits()>=UINT16\u MAX/4){
日志(信息)若要跳过此错误,您可以对您的发行版或调试版本使用Progourd minify Enabled选项。如果没有帮助,请使用MultiDex应用程序。有关详细信息,请参阅本文档。若要跳过此错误,您可以对发行版或调试版本使用Progourd minify Enabled选项。如果没有帮助,请使用MultiDex应用程序。有关更多信息,请参阅此文档。可能64k是字节?可能64k是字节?看起来我的更新和绘图方法“病态地”很大,lol。源代码不错。@Androidcoder可能不是你的,而是整个编译过程。剥离未使用的方法也可能有帮助;只是不知道这是在更新之前还是之后发生的t检查发生。最佳解决方案是低于16k指令计数。剥离未使用的方法无关紧要,因为此错误在调用该方法时触发。第一次调用该方法时编译失败,因此下一次调用也是“第一次”再次失败,下一次,下一次……编译一个大型方法需要CPU时间和电池电量,因此在循环中执行此操作是一个相当大的问题。(在我的例子中,它涉及使用解析和中等复杂的语法。您好,搜索引擎。)看起来我的update和draw方法“病态地”很大,哈哈。源代码不错。@Androidcoder可能不是你的,而是整个编译过程。剥离未使用的方法也可能有帮助;只是不知道这是在检查发生之前还是之后发生的。最佳解决方案是低于16k指令计数。剥离未使用的方法没关系,因为这个错误是在调用方法时触发的。第一次调用方法时编译失败,所以下一次调用也是“第一次”并再次失败,下一次,下一次……编译一个大型方法需要CPU时间和电池电量,所以在循环中执行这一操作是一个相当大的问题。(在我的例子中,它涉及到解析和一个中等复杂的语法。您好,搜索引擎。)问题涉及单个方法中的指令数;android的限制低于JVM的限制。Multidex涉及应用程序中的方法数。问题涉及单个方法中的指令数;android的限制低于JVM的限制。Multidex涉及应用程序中的方法数在…上