Android ART 运行时是不是具有与 Dalvik 相同的方法限制限制?
Posted
技术标签:
【中文标题】Android ART 运行时是不是具有与 Dalvik 相同的方法限制限制?【英文标题】:Does the Android ART runtime have the same method limit limitations as Dalvik?Android ART 运行时是否具有与 Dalvik 相同的方法限制限制? 【发布时间】:2014-02-24 18:09:16 【问题描述】:android ART 运行时是否具有与 Dalvik 相同的方法限制限制? 目前,主 dex 文件中有 64k 个方法的限制
【问题讨论】:
【参考方案1】:问题不在于 Dalvik 运行时或 DEX 文件格式,而在于当前的 Dalvik instructions 集。具体来说,各种方法调用方法,如下所示:
invoke-kind vC, vD, vE, vF, vG, meth@BBBB
B: method reference index (16 bits)
你可以在一个 DEX 文件中引用非常多的方法,但你只能调用前 65536 个,因为这是你在方法调用指令中的全部空间。
我想指出,限制是引用方法的数量,而不是定义方法的数量。如果您的 DEX 文件只有几个方法,但它们一起调用了 70,000 个不同的外部定义方法,那么您将超出限制。
解决此问题的一种方法是添加采用更广泛方法引用的附加指令。一种称为“巨型操作码”的方法在 Android 4.0 (ICS) 中实现并发布,但从未完全付诸实施,后来成为removed from the tree。 (我偶尔会在这里看到来自“dx”的错误消息,这些帖子引用了巨型操作,或者来自stumbled over them 的开发人员。)
注意这不是Facebook hack 解决的问题。这是由于用于保存类/方法/字段元数据的固定大小的缓冲区。那里没有特定于方法的限制;您可以通过拥有大量字段来炸毁缓冲区。
我的理解是,ART 的当前实现处理的指令集与 Dalvik 相同,所以情况不会有什么不同。
【讨论】:
“但是它们一起调用了 70,000 种不同的外部定义的方法,你会超出限制”——什么才算是“外部定义的方法”? (Android 框架类?还有什么需要注意的吗?)。谢谢! 我的意思是在单独的 DEX 文件中定义的方法。对于大多数应用程序来说,这只是框架和核心库/使用库的东西。 FWIW,这就是为什么使用多 dex 解决方案 (android-developers.blogspot.com/2011/07/…) 将您的 DEX 文件一分为二并不会留下两个 DEX 文件,每个文件的方法引用数量正好是一半。 我遇到了相同的dexdeps
工具并编写了一个更完整的dex-method-counts
工具,使用它来输出(每个包/类)方法计数:github.com/mihaip/dex-method-counts
@fadden 您说限制不在于定义的方法数量,但是如果您采用一个空的 Android 项目并添加一个具有 65536 个空方法的类并且不调用其中任何一个,您仍然会得到异常。是我遗漏了什么还是你说错了?
@cdroid 本地定义的方法被隐式引用,无论它们是否在本地调用。我试图表明在单个 DEX 中定义超过 64K 的方法并不是失败的唯一途径。表中可能存在一些“死区”。 (模糊相关:在某一时刻,我试图通过“垃圾收集”索引来减少 VM 的并行解析实体表的内存占用,但结果还不足以带来额外的复杂性。请参阅 @ 中的大量 cmets 987654327@.)【参考方案2】:
Anwar Ghuloum 在thisAndroid 开发者后台一集中告诉他们,他们不会在不久的将来修复字节码。 相反,从 Android L 开始,它们将通过将所有 dex 文件(来自 APK)折叠成单个 oat 文件来原生支持多 dex。
【讨论】:
嗯。 pre-L 设备会做什么? 支持库的下一版本将涵盖 API 4+ 设备。在这里查看我的答案:***.com/a/26196397/1233652以上是关于Android ART 运行时是不是具有与 Dalvik 相同的方法限制限制?的主要内容,如果未能解决你的问题,请参考以下文章