从我为什么叫Gregorius到java虚拟机漫谈

其实我是一个标题党,不小心把大家吸引进来。从这篇文章开始分享一些真正的技术方面的东东了,为了使文章更具有可读性,内容会穿插一下小故事或八卦,心得等。文章力争不局限于技术方面的人员阅读,所谓授之以鱼不如授之以渔,文章以轻松的口吻跟大家聊一下技术。

我为什么叫Gregorius

下面开始切题,几年前当我开始看《linux 内核完全剖析》这本书时,同时也了解到传奇人物linus的彪悍人生,非常有个性的一个人,爱憎分明,大学时就写出了linux内核,一直到现在都掌控着内核源代码的核心,大名鼎鼎的github就是linus不满现有源代码版本管理一气之下写出来的。此书中有个对时间处理的函数,用途是取当前时间到初始时间的值,unix系的系统时间都是以1970-01-01为起点的,之所以以这个时间为初始时间是因为之前系统都是32的,只能表示68年的时间,作为权衡以此时间作为计算机的纪元时间。

此时间函数linus加了注释,大致意思是为什么不用闰年呢,闰年又称为称为"儒略历"或"恺撒历",由古罗马的恺撒在公元前46年制定的,1582年罗马教皇格里高利十三世(Gregorius XⅢ)对"儒略历"又进行修改,所以我的名字就来源此。

java虚拟机的诞生

java虚拟机是java能够跨平台运行的基石,自从java诞生以来,虚拟机的发展可谓是百花齐放,就连不可一世的微软也是java的铁杆粉丝,也曾开发出自己的java虚拟机,但是sun一纸诉文将微软告上法庭,结果促成了.net的诞生,可谓一失足成千古恨,不然java现在可以一统江湖。

如果你看完《linux 内核完全剖析》这本书或者对《via clr c#》有所了解,那么再来看java虚拟机相关的东西那就是相当容易了。

编译原理

首先从计算机的编译原理开始,对于传统的计算机编译过程来说,按部就班分为词法分析,语法分析,抽象语法树,解析执行。但是对.net和java来说,不能走寻常路,因为两者都是跨平台需要,都有一个中间结构,对于.net来说就是il和clr,对于java来说就是虚拟机指令和虚拟机了,这些指令操作的都是自己的虚拟存储设备,如果需要转为物理地址,需要动态解析,java为了兼容大多数虚拟机的优化,把之前静态编译阶段的优化都放到了动态解析阶段来。

体系结构

我们所说的java虚拟机指的是hot spot虚拟机,是sun之前收购过来的。虚拟机的存储结构主要分为程序计数器,java虚拟机栈,本地方法栈,java堆,方法区,运行时常量,直接内存,堆主要用来存放对象,栈用来存放方法变量这些。java对于c++的优势主要在于gc,垃圾回收机制,回收的主要内容就是堆上的东西,栈不需要回收,用完自动清空,对c++来说最大的痛苦莫过于指针操作,一不小心就把系统整挂了,所以自从有了垃圾回收机制语言的出现,程序猿们从此过上了快乐的生活。

垃圾回收算法

垃圾回收算法又称为休克算法,只要垃圾回收机制启动,就像给虚拟机施了魔法一样让,整个世界停止下来。接下来就是妈妈开始打扫卫生了,那妈妈怎么知道你的东西要不要回收呢?方式有很多种,限于篇幅我们直接说主流的方式,就是根引用算法,所有的东西都是妈妈的,妈妈在打扫时首先会记录一下谁在用,打扫阶段问你还用不用,如果都不用了,就把它回收回去,下次想用再找妈妈申请。

CLR Loader Vs Java ClassLoader

双亲委派模式是java类加载模型,类在加载时优先使用父类的加载器进行加载,同一个类只能在同一个类加载器里面加载一次,不同的类可以在不同的类加载器进行加载,但是不同的类加载器加载的类引用是不同的,就是表现为不同的实例。CLR 可以加载类的多个版本,但是只能通过AppDomain进行卸载,扩展性较差。我的结论:Java ClassLoader简单优雅、功能强大、非常灵活,但对多版本不提供支持;CLR Loader非常简单、支持多版本、但不太灵活且扩展性稍差。

语法糖

java从1996年以来,基本上是每两年发布一个版本,由于09年的oracle 收购案导致jdk 1.7迟迟没有开发出来,然而.net在此前后按部就班推出了较多重要的版本,表现在语法糖之间的差异与java越拉越大。语法糖可以提高程序猿的生产力,也是语言先进性的一个重要标识。

真假泛型

java的泛型只是一个语法糖,java采用类型擦除来初实现的泛型,在运行时将泛型转为原生类型来进行解析,所以java的泛型又称为假泛型。.net的泛型实际上是一个真正的类型,是CLR直接支持的,也称为类型膨胀,所以.net的泛型为真泛型。假泛型也是java经常被诟病的原因。

java虚拟机博大精深,本文只是浅尝辄止,文中如有不当,敬请批评指出。

你可能感兴趣的:(从我为什么叫Gregorius到java虚拟机漫谈)