Objective-C 的 Runtime 与 Java 的 Runtime 有何差异?

或者说,两者的动态性方面有什么差异?
关注者
97
被浏览
7,235

3 个回答

运行:Objective-C runtime 运行 native code 。Java VM 运行 byte code。

垃圾回收:Objective-C runtime 有过短暂的使用 conservative GC。但是 conservative GC 对于 native code,特别是经过优化的 native code 并不有效。所以目前 Objective-C 没有 GC(只有 ref-counting 的内存管理策略)。Java VM 有 generational GC。

动态机制:Objective-C runtime 对 class method 的调用是通过全局名称查询。而 Java VM 是通过类似 C++ 的虚表机制。所以 Objective-C 无须 explicit interface 就能实现多态,能动态的给 class 添加方法,Java 则不行。这是很讽刺的,一个基于 byte code 的语言居然不如一个 native code 的语言动态。(Java 有 reflection 机制,但是这套机制是独立于 JVM 本身的静态调用机制的。Reflection 给予了你操作虚表的能力,但是基本的 JVM 仍然是通过虚表这个静态机制完成的。)

对象:Objective-C 考虑到和 C 的交互,对象不能 relocatable。Java 的对象可以 relocate,因为没有 raw pointer 。

其实Objective-C的Runtime至少有两种实现:

OS X Objective-C 2.0 runtime library

GNU Objective-C runtime API

我一点也不了解Java的Runtime,:D

但是如果正好你知道Java的Runtime的运行机制,你可以拿它来对比下面的Mac OS X的实现。

和苹果产品一样,OS X Objective-C 2.0 runtime的设计理念相当简洁:

基于标准C,

编译器把代码中的所有的method调用转换为C函数的调用,

通过method的selector在类的继承的层次结构上溯查询method的地址指针,然后运行。

所以,Mac OS X上Objective-C应用程序是虚拟内存中机器码的直接(无码)运行。(喂~

既然是直接运行机器代码,Objective-C的runtime其实只是一个法则,在实际的process上,内存中,它并不因存在而自身消耗哪怕是一丁点的系统资源。