Android 上为啥会有65536的限制,解释下原因
该文章已经收集到面试题整理(可在首页点击底部 Tab 看到)。
在这之前的一篇文章中,我们模拟了关于65536问题的面试场景 关于 65536 限制与 MultiDex 会在面试中被问到的问题可能都在这了。
然后归纳出了面试中可能会出现的问题:
-
Android 上为啥会有65536的限制,解释下原因。
-
Android 官方是如何解决65536问题的?MultiDex 在打包阶段和 app 运行阶段分别做了什么?
-
使用 MultiDex 可能会造成什么问题?
-
使用 MultiDex 后首次启动 app 有什么优化方向吗?
-
如何将指定的 class 打进 mainDex ?
那么这篇开始回答第一个问题:Android 上为啥会有65536的限制,解释下原因。
日常开发中,工程中有大量方法是很常见的,但当方法数超过65536时,编译时会出现这个错误:
一个 dex 文件的方法引用数不能大于 64k,64k 的准确值是(64 * 1024 = 65536)。
65536 这个值是咋来的呢?我们依然从源码入手:
全局搜索 ; max is ,发现 MemberIdsSection#getTooManyMembersMessage 使用了:
再看看 getTooManyMembersMessage 被谁调用的?
那 MAX_MEMBER_IDX 的值是多少?
那么 65536 这个值是咋来的,我们很清楚了,而且从源码中我们还得知除了方法数有限制之外,成员变量的个数也被限制了。
但是,这还不是面试官想要的答案,源码中的 MAX_MEMBER_IDX 为什么要定义成 0xFFFF 呢?
这个我在 stackoverflow 上找到了答案:
invoke-kind {vC, vD, vE, vF, vG}, meth@BBBB 是啥?来看看关于 davilk 指令的官方文档:
解释一下:
invoke-kind (调用各类方法)指令中,方法引用索引数是 16 位的,也就是最多调用 2^16 = 65536 个方法,这就是 DexFormat 中 MAX_MEMBER_IDX 为 0xFFFF 的原因。
说个题外话,在看这个 davilk 指令的时候 ,我注看到了 vC..vG 这几个参数寄存器,心中就产生了一个疑问,Java 方法里的参数个数上限是多少呢?感兴趣的可以试试。
关于 Android 上为啥会有65536的限制的解释就是以上了,希望对大家有帮助。
转载自:https://juejin.cn/post/6844903533611843592