multidex 讨论

楼主: HuangJC (吹笛牧童)   2016-06-23 12:44:34
http://www.cnblogs.com/yydcdut/p/4887157.html
这篇看过,虽然通篇中文,不过处处难懂 Orz
1.为什么 method count 不得多于 64K?
从前 x86 时代,我是有学机械语言及组合语言的
所以对于一个 function 不能大于多少 size 可以理解
原因就是一个 jmp 或 call 指令,其后只带几个 byte
(如果只带一个,限制就在 256 byte, 带两个,限制就在 65536 byte)
而 x86架构下有所谓"段暂存器"(哇塞,考古到这超怀念)
因此如果只用两个 byte 来表达位址,那就是段内跳跃
只用一个 byte,常见的不是绝对寻址
(取出目前这道指令的位址,把它 16位元的 hibyte 留着,
lobyte 改以 jmp 后带的一个 byte 取代)
而是相对寻址
(取出目前指令位址,加上 jmp 后带的一个 byte,
而且这个 byte 是当成 signed,有正负号的,因此可以往前后跳 127 byte)
更大的则是带四个 byte, 那就可以做32位元跳跃
至于以前虽然有 32 位元位址观念,但其实只有 20条位址线
这种偷吃步引起的奇怪限制,讨论就更多了
我们其实都是跟着 compiler 给的架构一起成长 XDDDD
本来想详述这段,但一来离题,二来无法讲得干净
跳回 android dex 继续谈:
我明明看 java 编出来的 code 里面有一堆 function name
(因此乱恐怖的,如果不搅拌一下,根本可以从执行档反组译出程式来)
所以我认为它的 function call 实现方式,应该就是直接去 mapping function name 吧!
字串能有多少变化,funtion 就能有多少,不是吗?
java 又没把指令 compile 完后,变成只是个数字
fun1
fun2
fun3
.
.
.
fun65536
像上面那样,如果真的指令只能用数字 access,那我就理解它指令数只能有 64K 个
可是比如 reflect function,都是用 function name 把函式指标取出来
看来即使编译成了执行档,function name 也没被丢掉
这种寻址法其实很像 win 之下的 DLL, 可以用 GetProcAddress
https://msdn.microsoft.com/en-us/library/windows/desktop/ms683212(v=vs.85).aspx
它传入的参数可是字串,是 function name
那怎么会有 64K 限制?
或许 Java 是允许用 function name 寻址
但无论如何它内部就是非得用 function number 来呼叫
(可能是这样可以写 table, 不用一直做字串比对,速度会比较快?)
好吧,那就先接受这个限制(反正我又写不出 compiler,我不接受也不行)
但切 multidex 我又会有另一个问题
2.若我用 DLL 来理解 dex 的话
那不只是要把太大的程式切成两个 dex
而且,两个 dex 间,还不得互相呼叫
比如,若我的程式已经有 65538 个函式(就是只多两个)
那并不是切成相等的两块,每块 32769 个函式就好
而是,第一个 dex 的函式,都不能去呼叫第二个 dex 的函式
因为有寻址空间误会的问题
如果切出一个 main-dex
然后由它加载 dex1 (function 相加总数不能超过 64K)
等要使用 dex2 时,dex1 还得退出
(这时 main-dec 加 dex2 function 总数还是不能超过 64K)
那我就懂了
(喔,那就和 win 下写 dll 的问题一样了)
作者: LPH66 (-6.2598534e+18f)   2016-06-23 13:45:00
64K 是 dex 的指令集设计上的问题其实 java 的 bytecode 本来也是有这限制的invokevirtual 后面跟的数字也是最大 64K但 java class 的函数计数只限于单一 class所以除非是超巨型 class 不然应该不会碰到但 dex 是把所有 class 打包成一个超大包 dex因此所有 class 的内容全部加在一起才会撞到限制至于 function name 的问题, 不论是 bytecode 或 dex都是有一个“method 列表”, 用你提到的字串表示 method实际的 bytecode / dex assembly 上还是使用列表索引class bytecode 其实某个意味上还更惊悚: 它只有一个常数池所有物件/函数/成员变量等等的参考都在常数池里有位置不像 dex 是物件一个池, 方法一个池, 字串一个池等等这当然也跟 class 一般大小并不大有关就是
作者: ssccg (23)   2016-06-23 18:08:00
其实multidex就是改成很多个class file的方向啊后续的问题是旧版Android没有原生支援读取多个dex造成的
楼主: HuangJC (吹笛牧童)   2016-06-23 18:21:00
所以新版完全无痛解决了吗?毕竟公司现在只有我有4.3如果说维护成本太高,5.0以上市占又高,我们可能直接舍弃那些维护的 code;交给 compiler 就好了..
作者: ssccg (23)   2016-06-23 18:26:00
5.0以后其实是换了一套VM(ART),会在安装时先把所有dex再compile成另一格式的执行档oat,VM和档案格式都换了自然可以修掉当初设计Dalvik指令集的错误了..AS可以写Java,新增module选Java Library,然后在Run >Edit Configurations自己新增一个Application类型的设好Main class就能跑了,console就是Run那个视窗bytecode java最简单就用JDK的javapdex用android SDK的dx --dump或dexdump
作者: swallowcc (guest)   2016-06-23 22:59:00
mac可以装多重版本jdk, 然后用command line切换版本

Links booklink

Contact Us: admin [ a t ] ucptt.com