火球法师
精华
|
战斗力 鹅
|
回帖 0
注册时间 2016-12-9
|
机器码这个东西是个很神奇的玩意, 和运行环境高度耦合, 绝对不是你想的那样在A机器上编译, 拿到B机器上就能直接运行的.
编译器把程序变成机器码是个很复杂的过程, 这个过程中需要大量用到底层的各种信息, 包括CPU指令集, 操作系统提供的各种接口, 内存管理机制等等. 一个与运行环境完全耦合的程序, 其运行效率是非常恐怖的. 但代价就是系统耦合度极高, 基本不具备复用性和扩展性. 讲得直白一些就是一机一程序, 拿到另一台机器上就没法用
如果你同时部署过Java程序和C++程序就会发现这种有趣的区别. Java依托于JRE, JVM, 在Windows环境下编译的.class, 拿到Linux服务器上立刻就可以运行, 因为.class其实并不是真正的机器码, 运行时还要依托于JVM进行重编译, 这种做法降低一部分效率, 但是极大的提升了跨平台的通用性, 使程序和运行环境的耦合度大幅度降低.
C++完全不同, 写C++程序尤其是那些做外包的, 拿到需求第一件事就是先搭一个和生产环境尽可能接近的测试环境, Linux内核版本, 编译器版本, 驱动版本, 各种依赖库都要完全一样. 在测试环境上运行通过以后拿到生产环境还要再编译一遍才能拿来用.
知乎那个回答猜测了两种可能, 一是JIT + AOT, 二是在发布时APK已经被编译好了. 我觉得第二种可能性比较大, 但并不是简单的在打包APK时就进行了完整编译, 原因正如之前所说, 机器码和运行环境是高度耦合的, A环境下编译的机器码拿到B环境下未必能运行.
这其中的操作空间主要在这里: 手机不像服务器, 同一型号甚至同一系列的手机, 其硬件配置在程序角度来看并没有太大区别, 因此可以在编译器中预置手机型号的模板, 其中包含运行环境的底层信息. 这样编译完成后就是高度耦合的APK包. 当然这么做也不是没有缺点, 那就是这个APK只能在这个型号的手机上使用, 拿到其他手机上直接无法运行甚至出错.
|
|