您的位置:首页 > 编程语言 > Java开发

什么是JVM (Java Virtual Machine)?

2012-02-19 09:31 369 查看

JVM 简介

当人们一提到Java语言就会立即想到它是一门编译一次,随处运行的语言。人们无不赞赏它的平台独立性,也叫平台无关性。Java还有一个被人们称道的特性就是它的安全性,也就是保护运行Java程序的机器不被恶意代码伤害。而Java能够做到这两点全靠JVM。

JVM 是 Java Virtual Machine 的简写形式。翻译成中文就是Java虚拟机。虚拟机是相对于物理机(Physical Machine)的一个概念。JVM是Java技术的基石,它负责实现Java的硬件和操作系统的独立性,保护用户机器不被恶意代码侵害,同时使Java的编译代码足够小。编译出来的代码足够小是为了方便在网上传播,其实主要是针对Java Applet的,也就是当你需要在客户端下载Java编译后的代码然后运行的时候就不得不考虑需要下载的文件的大小了。在Java企业级B/S模式下这个问题不是那么突出。

JVM是在不同的硬件和操作系统之上的一个抽象层(如下图)。它如同OS一样定义了指令集,并管理自己的内存区。Java就运行在这个抽象层之上,JVM对Java屏蔽了底层硬件和操作系统的不同,这就实现了平台的独立性。同时因为Java运行在JVM上,JVM就像一个沙箱一样控制着Java的行为能力,也就可以避免恶意的代码侵害底层的OS。其实就是JVM的安全性对Java的行为能力做了限制。





一提到Java就会想到Sun,但是JVM并不是Sun一家才有的,其实JVM只是一个说明书,或者说是技术规范。谁都可以实现自己的JVM,只要符合这一规范(见参考阅读【1】)。而Sun是第一个实现了JVM的,也是这一规范的主要制定者。

JVM作为一种规范并不限制你的实现技术,当你具体实现自己的JVM的时候,你肯定要考虑你的JVM实现要运行的具体操作系统和硬件设备,还要考虑你对JVM的特殊的需要。

JVM虽然为Java而生,却不认识Java。它只能读懂class文件,一种二进制文件。处于安全考虑,JVM对class文件的格式和结构有着严格的限制。如果想在JVM上运行Java程序,就必须先把Java程序编译成class文件。换一个角度看,如果你能把非Java语言(比如ruby,groovy等)编译成这种class,也能在JVM上运行。这也衍生了一个新的趋势:多语言运行在JVM上。既扩大了JVM的影响力,又为新兴语言方便搭乘JVM这辆快速列车提供了车票。(见参考阅读【2】)

可以看出JVM作为一个抽象层,对它的下层(OS)和上层(Java)都有着很好的独立性。

Sun (Oricle)的最新的JVM实现就是Java HotSpot Virtual Machine。

HotSpot JVM

HotSpot 是Sun开发的新一代高性能JVM实现。HotSpot 具有动态编译( dynamic compilation )和自适应优化(adaptive optimization) 以改善性能的特性。HotSpot是作为JRE的共享库而存在的。HotSpot在JRE里面分为client HotSpot JVM 和 server HotSpot JVM。顾名思义,client jvm是为客户端量身定制的,具有快速加载和占用较少内存的特性,它解释执行代码,执行效率比较低。相反server jvm是为服务器端打造的,加载比较慢,但是具有只适应优化动态编译的能力,具有较高的运行时效率。他们分别被安装在JRE_HOME/lib /client 和JRE_HOME/lib/server下。如果你只是安装了JRE,那就不包含server jvm,如果你还安装了JDK,那就server jvm。在启动你的Java程序的时候你可以通过启动选项-client或-server来选择采用什么jvm。

HotSpot 的优良特性

相比之前的Sun的JVM实现:

1. 内存模型更为优良

【快速】HotSpot采用直接对象地址指针代替以前的间接指针,大大提高了性能。当你定义一个对象的时候,这个变量就是对象的引用。在以前的JVM里,这个引用不是指向对象的地址,而是指向对象地址的指针,这样,当JVM要访问这个对象时就需要寻址两次。这样做的好处是在GC(垃圾回收)的时候,如果需要移动对象数据的位置(为了减少碎片),只需要更新对象地址的指针,不需要更新对象引用变量的值。方便了垃圾回收,但形成了性能的瓶颈。HotSpot就解决了这个性能问题,它用直接的对象地址指针作为对象应用的值,当需要移动对象数据的时候,由垃圾回收程序负责更新对象引用的值。这个实现方式有点像C了,当然也获得了C一般的访问速度。

【节约空间】HotSpot采用两个机器字来表达对象头信息。以前是用3个字来表达的。因为根据经验两个字足够了。这无疑大大节省了内存的开销。对于一般的应用可以基本上可以节省8%的heap大小。但是对于对象数组还是用3个字来表达。第三个字存储了数组的大小。

【简单】 类,方法一起其它的反射数据也都被JVM表达成对象。当然这些对象不能像你自定义的对象一样被你引用。这才符合“一切都是对象”的理念嘛。这有点像ruby和python了。这样不但可以简化jvm实现的对象模型,更使得gc可以像回收普通对象一样回收这些反射数据对象。

【native的线程支持】 Java方法和native方法共享操作系统的stack,采用相同的线程模型。其实这样jvm就将线程调度和stack的管理交由os处理了。这不仅可以使java方法和native的方法可以快速相互调用,还使得jvm可以透明的利用os的线程优化方法。当程序从单处理器扩展到多处理器的时候也可以透明扩展。

2. 垃圾回收更为灵活

HotSpot采用分代回收的垃圾回收方式。在此基础上提供多种垃圾回收算法来满足实际应用的不同需求。

3. 超快的线程同步

HotSpot 监控工具

1. Jconsole:jconsole是一个在JDK 5中就存在的GUI工具,现在附加在已经运行的JVM。

2. jhat是一个堆栈分析工具。

3. jmap:它是一个小的能从JVM中得到堆栈柱状图和堆栈快照的工具。

4. Jstack:jstack能够打印Java堆栈追踪和检测所有平台上的死锁,你可以使用jstack –l来打印java.util.concurrent锁的列表。

参考阅读

【1】 http://java.sun.com/docs/books/jvms/second_edition/html/VMSpecTOC.doc.html
【2】 http://developer.51cto.com/art/201007/215147.htm
【3】 http://www.oracle.com/technetwork/java/whitepaper-135217.html
本文出自 “祥哥的珍藏” 博客,请务必保留此出处http://ctomentoring.blog.51cto.com/4445779/783158
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐