百科问答小站 logo
百科问答小站 font logo



微软当年的 J++ 究竟是什么?为什么 Sun 要告它? 第1页

  

user avatar   rednaxelafx 网友的相关建议: 
      

目前排名第一的

猫杀

的答案不错。我想就所谓“Microsoft J++”到底是什么稍微补充几点。

本文提到的“Sun JVM”主要说的是Sun JDK 1.0.2带的那个元祖JVM。它在后来的Sun JDK里被称为Classic VM,再后来被HotSpot VM所替代。

当时(Sun JDK 1.0.2)的Java跟现在的Java不可同日而语。别提标准不标准,当时的Java毛都没有,很多东西所谓“标准”就是“Sun怎么实现”。

为什么Sun要告微软?微软“不乖”,“擅自”扩展Java让它在Windows上变得更好自然是一方面;另一方面Sun对它的Java合作伙伴们普遍态度恶劣,非常傲慢和小心眼,这才是更重要的方面。

这方面请参考另一个问题的回答:

如果当时 Sun 没有起诉微软,而微软继续保持对 Java 的热情的话,Java 的现状会是怎样? - RednaxelaFX 的回答

另外,想从别的侧面看看当年Sun的行为,看看1997年Sun在benchmark上作弊的事情:

Sun accused over JIT compiler results

。这还不是Sun第一次做这种事嗯。

关于控告的过程,请参考当时的新闻稿:

Washingtonpost.com: WashTech -- U.S. v. Microsoft Special Report

Microsoft J++

Microsoft J++是外界对微软所实现的Java的开发套件和运行时环境的统称。微软自己其实并没有一个叫做“Microsoft J++”的产品(或语言)。微软一直觉得自己实现的就是Java语言,只是稍微根据Windows环境的需要“增强”了一点而已。

微软在JDK 1.0.x时期就获得了Java的授权,将Java移植到Windows平台上。当时的Java真是烂得掉渣,JVM的速度又慢,Java核心库的功能又是要啥啥没有:

例如说能用的容器数据结构就只有Vector、Stack(包装了Vector)、Hashtable(不允许null值)、BitSet,连LinkedList都还没有——“谁会要用链表呢”。

java.math、java.text、java.sql、java.rmi之类的重要的类库都还不存在,locale支持还不存在,图形库只有又慢又不好用的AWT⋯

嗯对,JDK 1.0.2的时候连反射都还没API,java.lang.reflect也还不存在。Java语言里“接口”这个语言结构也还不存在。

JNI(Java Native Interface)标准也还不存在。Sun JDK 1.0.2只有一个非常原始的native interface,而它允许native代码直接访问Java对象的内部结构,既不安全也不可移植。更新信息可以参考当时的文档:

Integrating Native Methods into Java Programs

而这个时候Windows上已经有很多可用的库,更重要的是:

  • 它们有很多都以COM的方式暴露接口
  • Java的对象技术其实跟COM有许多重叠之处

于是让Java能够更好的利用Windows上已有的资源,真正在Windows上成为一等公民,微软给Java添加了:

  • J/Direct与RNI(Raw Native Interface):用于与native代码交互
  • Java/COM:让Java能够使用COM的库,也让Java程序能够暴露出COM接口,便于与其它程序交互。参考这里:Can You Implement COM Components Using Java?
  • 委托(delegate):现在Java 8也有lambda,大家都知道这个是什么了。当时要引入委托主要是为了更好的支持事件模型的回调。详情可以参考微软对Java委托的专利:Patent WO1999063433A1,以及MSDN的文档 Delegates in Visual J++ 6.0。微软当时为Java实现了委托之后把全套代码交给了Sun,向Sun申请添加该功能到标准Java。结果Sun暴跳如雷急忙批判微软要分裂Java…
  • 还有一大堆的库。例如Windows Foundation Classes (WFC)。WFC包装了Win32和DHTML的图形组件库。Win32的部分跟后来.NET的Windows Forms(WinForms)很像。
  • 等等⋯

微软版的RNI在Sun版的JNI之前就已发布,自然就不大愿意再实现一个功能非常相似的东西。但微软决定不在MSJVM里实现完整的JNI成为了后来打官司的关键因素之一。

当年微软给Java加了的功能,现在Oracle在一点点给Java加上⋯

  • Java SE 8给Java语言加上了lambda与method reference;
  • Java SE 9正在计划给Java加上跟J/Direct类似的新的、更方便的native interface

Microsoft Visual J++

Visual J++,这是一个实际存在的产品的名字。它是一个用于开发Java应用程序的IDE,里面还包含有IE3.0之类的“附属物”。Visual J++有单独发布的版本,后来被整合到Visual Studio里发布。

Microsoft SDK for Java (MSJDK)

这是Sun JDK的微软版对应物,独立于Visual J++免费发布。它包含开发Java应用程序所需要的工具套件,例如Java源码编译器 jvc(与Sun JDK的javac对应),Java的命令行启动程序 jview (与Sun JRE的java命令对应) ,Java Applet Viewer,Java核心库,还有Java虚拟机(MSJVM),等。

有个有趣的工具叫做 jexegen。顾名思义,它用于为Java程序创建一个可执行程序,把Java程序所需的Class文件打包在生成的exe里。这跟后来.NET Assembly的做法很接近:它是一个PE文件,不过启动之后马上会去加载MSJVM来执行打包的Class文件。能生成出可执行文件让Java写出来的程序能更符合Windows的用户习惯。

Microsoft Compiler for Java (jvc)

jvc 是微软自己实现的Java源码编译器,应该是用C++实现的(求证)。

它的编译速度非常快,而且编译时会做许多优化,编译出来的代码质量也比较高。

相比之下,同时期Sun的javac是用Java实现的,编译速度慢一些;虽然也做一定量的优化,但没 jvc 做得深。

jvc 跟当时IBM的

Jikes编译器

(跟后来的Jikes RVM不是同一个东西)地位相似。两者都用native语言实现(Jikes用C++),编译速度都比较快,而且都做比较多优化。

同年代同样用native语言实现的Java源码编译器还有Symantec Café Compiler。

jvc 支持所有标准的Java语言特性,外加支持如delegate、J/Direct之类的微软扩展的特性。

话说有个黑历史非常搞笑:Sun在控告微软的jvc不兼容Java规范的时候,指责jvc生成的Class文件通不过TCK1.1;然后微软不但说明Sun没用对命令(故意打开了微软扩展来测试),而且进一步说明Sun的javac其实也不能完全通过TCK1.1;关掉了扩展的jvc能通过的TCK1.1测试比Sun的javac能通过更多。

Microsoft Virtual Machine for Java (MSJVM, Microsoft VM, MSVM)

这是微软实现的JVM。最初的代码来自Sun授权的Sun元祖JVM,后来被魔改成Windows上最快的JVM实现。

IE3 Beta 1的时候带的MSJVM还只有解释器,到IE3 Beta 2就开始带有JIT编译器了。

MSJVM魔改了Sun JVM核心的每一方面。

  • 对象模型:Sun JVM的对象模型把“对象头”放在了handle里,使“对象头”跟对象实例数据分离到不同的地方了。MSJVM去掉了handle这层间接,于是把对象头与对象实例数据重新“粘”到了一块。关于MSJVM的对象模型,我在另一个回答里简单提了一下:为什么bs虚函数表的地址(int*)(&bs)与虚函数地址(int*)*(int*)(&bs) 不是同一个? - RednaxelaFX 的回答
  • 基于直接指针而不是基于handle的引用,访问效率更高。
  • GC:准确式的、分两代的copying GC。文档里还专门说了没使用mark-compact算法。当时的Sun JVM使用的是半保守式、不分代的mark-sweep(带可选compaction) GC。
  • 对象同步:使用synchronization block而不是老Sun JVM的monitor cache。在对像头里包含有一个指向synchronization block的指针;该指针位于对象的负偏移量上。后来的CLR的对象头采用了同样的布局。在对象头里持有这样的指针大幅减少了查找对象的monitor的事件。Sun JVM是维护一个全局的用hash table实现的“monitor cache”,把对象的handle强制转换成int当作key去查找这个cache里的monitor,每次查找都是一个hash lookup。
  • 线程:使用native线程,管理线程用的数据结构稍微调整过。Sun JVM在Windows上的版本用native thread,而在Solaris上的版本则是使用green thread(JVM自己调度的用户级线程)。
  • 添加了JIT编译器:Sun JVM在JDK 1.0.x的时候只有个很简陋的JIT编译器接口,但没有发布JIT编译器的实现。MSJVM改造了这个接口并且提供了一个当时性能还不错的JIT编译器实现,而且配合准确式GC提供必要的信息。
  • RNI:在Sun JVM的native interface的基础上衍生出的一套native interface。
  • Java/COM在MSJVM内的支持

MSJVM基本没怎么改动的可能也就是解释器的核心循环了。原本在Sun JDK 1.0.2的时候,Sun JVM的解释器循环用纯C实现,写得很直观但性能很渣;到Sun JDK 1.1.0的时候

改为用汇编实现

,写得比较高效,所以也就没啥必要魔改这部分,小改动然后直接用就好。顺带一提,Sun JDK 1.1.0的JVM的解释器,在x86上的版本是Intel贡献给Sun,而不是Sun自己写的⋯呃呵呵。

Sun那边的JIT编译器有好多黑历史⋯Sun JDK 1.0.2自己没有带JIT,不过有一个单独销售的产品叫“Java Workshop”,里面带有一个能插入Sun JVM的JIT,这个JIT编译器叫做“sunwjit”。

可以从

这里

下载到描述sunwjit的一篇文章(CompileJava97.pdf,“Compiling Java Just in Time”)。

后来Sun JDK 1.1.x的时候开始带JIT发布了,但却只在Solaris版上带有sunwjit,而在Windows版上带的是Symantec的JIT(“symcjit”)。

据说James Gosling原本自己写过一个JIT编译器,但是没发布被抛弃了。不知道这跟sunwjit是啥关系呢。

Microsoft Internet Explorer 3.0 (IE3.0)

IE3.0真是当年的技术急先锋。一方面搭载了JScript来跟Netscape的JavaScript抗衡,另一方面捆绑了MSJVM以便支持Java。

先写这么多吧⋯

=============================================

后话

所以说当时MSJVM至少可以从三个地方获取:IE3、Visual J++/Visual Studio、MSJDK。MSJVM的许可证也允许第三方程序捆绑它发布。

顺带一提,根据

Patrick Dussud在Channel 9上的一个访谈

里提到的,微软里其实还有过一小撮人做过一个非正式项目,是写一个全新的、“clean-room”(不衍生自Sun的代码)的JVM原型。这个项目最后没有进入产品。或许如果当年Sun没有禁止微软开发新版本Java的话,微软也会像IBM开发出全新、clean-room的J9 VM一样有自己独立的JVM。

然而历史没有如果。那个clean-room的JVM原型为后来的CLR的研发积累了不少经验。

我觉得现在这样也挺好的。.NET总算没把Java所有的历史包袱都带上,CLI(Common Language Infrastructure)的基础设计又比JVM的更进步和完善。




  

相关话题

  C#程序如何调用Python程序? 
  为什么c/cpp语言的函数好像没有按照驼峰命名法呢? 
  Fortran 目前仍然是科学计算领域使用的主要语言吗? 
  计算机随机生成一个数是不是真的是随机的? 
  微软 Surface Laptop SE 笔记本电脑正式发布,售价 249 美元,值得入手吗? 
  如何看待微软正式宣布收购动视暴雪? 
  为什么不流行国语编程? 
  现在(2021年)OSGi的发展前景如何? 
  刷完 LeetCode 是什么水平?能拿到什么水平的 offer? 
  微软选择在2014年这个时候公开MS-DOS 2.0和Word for Windows 1.1A的源代码,有什么意义? 

前一个讨论
工作中只能使用C#的基本语法,根本用不到任何如ASP.NET等成熟.Net技术,个人应该如何提高呢?
下一个讨论
为什么税收不会被视为对私有财产的一种侵犯?





© 2024-05-20 - tinynew.org. All Rights Reserved.
© 2024-05-20 - tinynew.org. 保留所有权利