【问题标题】: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 个方法的限制

【问题讨论】:

    标签: android dalvik art-runtime dex-limit


    【解决方案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。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-21
    相关资源
    最近更新 更多