- 浏览: 738580 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (439)
- 生活小感 (9)
- Java (65)
- 笔面经 (18)
- 算法 (45)
- 读书笔记 (1)
- Android (147)
- 设计模式 (7)
- C语言 (7)
- 职业生涯 (6)
- 网络 (5)
- 数据库 (3)
- Linux/Unix (21)
- C++ (7)
- 思考 (3)
- WinPhone (4)
- Git (6)
- http (1)
- UML (1)
- SQL (2)
- Ant (1)
- iOS (14)
- FFmpeg (22)
- WebRTC (10)
- Mac (2)
- web (0)
- TCP (2)
- Vim (2)
- OpenSSL (1)
- OpenGL (6)
- 多媒体 (10)
- cocos2d (2)
- svn (1)
最新评论
-
wahahachuang8:
我觉得这种东西自己开发太麻烦了,就别自己捣鼓了,找个第三方,方 ...
WebSocket初探【转】 -
ding335306:
这个目录下没有找到此文件
eclipse.ini in MAC -
songshuaiyang:
哥们写东西可真乱啊
Android获取cpu和内存信息、网址的代码 -
zhoutao_temp:
这是自己能看懂还是让别人能看得懂,您就不能把版面稍微整理一下吗 ...
FFMPEG源码分析 -
chriszeng87:
string2020 写道git clone --bare表示 ...
复制git库
转自 http://www.blogjava.net/duffblog/articles/66677.html
Java虚拟机的起源与构造
当我们说到“Java”这个词的时候,指的是四个相互关联的概念:Java语言、Java API、Java Class文件格式、Java虚拟机。整个Java体系是基于Java 虚拟机构造的,正因为如此,才能实现Java的安全性和网络移动性。Java并非是第一个采用“虚拟机”概念的体系,但却是第一个得到广泛运用的虚拟机平台。 “虚拟”,是一种隔离物理资源与逻辑资源的手段。Java虚拟机的“虚拟”,则是用来隔离物理机器、底层操作系统与Java语言规范实现的手段。
虽然Java是一种面向对象的语言,我们平时大量使用的,是对象间的多态、组合(Composition)、委派(Delegation),但当我们讨论虚拟机的时候,我们看见的基本概念却是“栈(Stack)”和“堆(Heap)”。根据冯诺依曼的“存储计算”模型,所有的代码都保存在代码空间中,随着程序计数器指针的变化进行程序的执行、跳转。Java虚拟机中没有寄存器的概念,方法调用是采用“栈”进行的,这是一种安全、简洁的方法。
Java虚拟机通过类装载器支持对类的隔离,这也是Java实现安全性的基础。每个类都具有自己的命名空间,在具有不同安全级别的沙箱中运行,因此不会产生低安全级别的代码来越权访问高级别代码的机会。类装载器的出现是Java虚拟机与大部分用C实现的虚拟机的显著不同之处。
Java虚拟机的另外一个显著特点就是实现了自动的垃圾收集。在往常,写程序的时候要牢记对象之间的关联,在每个程序块中假若申请了对象空间,就必须在出口释放掉,方法调用往往同时也就是对象的边界。而自动垃圾收集带给开发者的最大好处,就是可以非常方便地从整体上把系统的对象组织成一张对象图,只需往这张图中添加对象,维护对象之间的关联,却不需要自己做复杂的清扫工作。正是有了这种思维单纯的对象图的支持,OR Mapping(关系数据库与对象映射)技术在最近得以大行其道,设计模式也更容易被Java群体所接受。
虚拟机的优化
1995年第一代的Java出台之时,其虚拟机执行是依靠“字节码解释器(Byte Code Interceptor)”的,也就是说每条指令都由虚拟机来当场解释执行,这造成速度令人抓狂地缓慢。更有甚者有人开始总结许多的“速度优化经验”,比如说:“尽量把所有的代码都放在较大的方法中执行”与“少用接口”等等,这完全与Java语言的设计目的背道而驰,现在看起来是多么可笑的奇谈怪论,当时却是很多程序员津津乐道的经验之谈。无他,Java本身执行太慢了。Java生命的前十分之三就是如此缓慢地渡过的。
于是,Sun的工程师开始拼命想着提高执行速度。JIT静态编译器的出现是在1996年十月,Sun放出了第一个编译器。JIT编译器在每段代码执行前进行编译,编译的结果为本地静态机器码,执行速度有了质的提高。Symantec公司当时凭借其傲人的JIT编译器,在整个Java界受到热烈的追捧。在其后的1998年,Java 1.2发布的时候,附带了JIT编译器,从此Java的使用者终于可以抛开上面说的那些奇怪的“速度优化经验”了。
JIT静态编译器虽然可以解决一些问题,但是性能仍然和C/C++有很大的差距。对一段程序而言,一名优秀的程序员是如何来改进运行速度的呢?首先,他不会傻到把所有的代码都来优化,他会观察、思考到底哪段代码对整体性能影响最大?然后集中精力来优化这一段代码。按照经验,整个程序 10%-20%的代码,会占据 80%-90%的运行时间。用这种方法,在同样的时间、付出同样程度的努力后,这名优秀的程序员使整个程序的性能得到了很大程度的优化。HotSpot引擎,就是模仿人工的这种方法进行优化的。在程序运行的开始,Java代码仍然解释执行,但HotSpot引擎开始进行采样(Profiling)。根据采样的结果,决定某段程序是占用较多运行时间的,就认为它是“HotSpot”,它也就是目前程序的瓶颈, 引擎开始启动一个单独的线程进行优化。因为不象原始的 JIT编译器那样无差别的编译所有代码,HotSpot引擎可以集中精力来对HotSpot代码进行深度优化,这样这部分代码执行起来更加迅捷。之前的静态编译器只能按照预定的策略进行编译优化,而HotSpot引擎的优化是基于采样的结果的,因此这种方法对所有的应用程序都有效。1999年3月27日,Sun放出了第一个HotSpot引擎。在随后的2000年5月的JDK 1.3中,包含了HotSopt引擎,这也使1.3成了一个具有里程碑意义的发行版本。到这里,Java的十年生命,已经过去了一半。
HotSpot代表的是一种动态编译的技术。对Java这种大量使用委派、组合等面向对象特性的程序来说,动态编译比起静态编译来有显著的优势。比如Method Inlining。方法的调用是一个很耗时的操作,假若可以把方法调用直接内嵌到调用者的代码中,就可以节省大量的时间, 这被称为“Method Inlining”。因为涉及到类的重载,静态优化很难确切知道哪些属性、方法被重载,因此很难对method进行合并,只好在方法内部进行静态编译,假若每个方法都很小,静态优化能起到的作用也就比较小。而动态编译因为可以完全随时掌握类的重载情况,就可以把相关的方法合并进行深度优化。现代的Java程序,特别是在设计模式教育得到普及之后,大量使用类的继承、委派,形成了很多短小的方法,动态编译的优势就更加明显。
自从出现了HotSpot之后,整个Java界为之一振。
最近的五年,就是继续优化的五年。继续进行优化的方法有几条路,一是研究新的采样算法。因为采样关系到不同的优化策略,会对整体性能有比较大的影响。二是研究深度优化的方法。三是研究垃圾收集的算法。垃圾收集会带来程序短暂的停顿,这会带来负面的用户体验。于是,如何提高垃圾收集的效率,减少延迟,出现了五花八门的算法,比如渐进式收集、火车算法等。在多处理器的时候,如何利用多处理器进行并行收集也是研究的一个热点。这方面,BEA的JRocket走在了前面。
现实生活中的虚拟机
最后,让我们来盘点一下目前市面上可见的各个虚拟机。
首先要提到的,毫无疑问是Sun的虚拟机。作为大众心目中的“官方实现”,Sun拥有最大的用户群,并且拥有“兼容基准”的地位,其他虚拟机都必须要考虑和Sun虚拟机的兼容性问题。比如 JRocket就会在某些特殊情况下表现出和Sun不同的特性,可能对程序运行有影响。不过Sun也的确没有让广大用户失望,虽然在早期性能比不上Symantec,后来在1.2 的时候性能又被IBM超越,但Sun一直在努力革新,特别是 1.4.2之后,性能有了长足的进步。虽然JDK 1.5的虚拟机在性能上没有什么提高,但是增强了稳定性,据说修改了8000处bug,真是让人汗流不止。原来我们在1.4.2下面一直在享受这么多bug啊。
其次是老牌劲旅IBM。IBM的JDK在1.3的时代创下了最好的性能记录,从此树立了高端形象。特别是在其WebSphere产品中得到了很好的评价。其JDK也是最早支持64bit的JDK之一。到了现在,IBM JDK在高端仍然是和BEA可以一拼的。
然后是后起之秀,BEA的JRocket。说到BEA突然在JVM领域一夜之间异军突起,多少让人有些瞠目,不过它采取的战略特别简单:自己没有,索性花钱买了在此领域深有研究的JRocket,在前面加上BEA的标志就可以了。JRocket瞄准高端服务器市场,在多处理器环境下有不俗的表现。
除此之外,还有几个开放源代码的JVM值得一提。首先就是大名鼎鼎的JikesRVM。说起其大名,大多数人都知道Jikes编译器是 IBM开发的,效率比同等的javac编译器高得多,很多开发者都使用Jikes编译器来取代javac。而JikesRVM则是IBM开源出来的一整套虚拟机技术,包含了JIT,GC的完整实现,在其网站上也有众多的论文,实在是想要深入研究JVM者的绝佳资源([url]http://jikesrvm.sourceforge.net)[/url]。
Kaffe是一个老牌的JVM,不过现在已经很少听到了。作者撰写此文时,[url]www.kaffe.org[/url]网站已经没有响应,也不知道现在的情况如何了。
GNU则有两个计划:GCJ和GNU classpath。GNU classpath是一个底层实现,而GCJ是支持java的预编译器。
结束语
时光流转,轰轰烈烈的Java虚拟机性能争论仿佛还在耳边回响,现在新的争论却已经是“Java的性能是否已经超越C/C++”。Joakim Dahlstedt 是 JRockit 的主要架构设计师之一,他坚持认为,Java绝不是一种速度慢,效率低的语言,JVM 是一个关键的组件,确保了系统的部署与运行和开发一样快速、轻松。特别是在目前开发趋势是采用大量预制的框架时,动态编译有可能比C/C++这样的静态优化获得更好的性能。
附:动态编译的概念: 程序运行时,JIT 编译器选择将最频繁执行的方法编译成本地代码。运行时才进行本地代码编译而不是在程序运行前进行编译(用 C 或 C++ 编写的程序正好属于后一情形),保证了可移植性的需求。
发表评论
-
Java Classloader机制解析
2015-07-14 14:14 851做Java开发,对于ClassLoader的机制是必须要熟悉 ... -
JVM Internals
2014-12-05 11:04 786This article explains the ... -
JVM必备指南
2014-11-01 11:20 478本文由 ImportNew - xiafei 翻译自 ant ... -
open jdk源码下载地址
2014-10-13 23:19 1121OpenJDK 和Oracle JDK 共用了大量相同的代码 ... -
Java中System.loadLibrary() 的执行过程
2014-10-10 11:45 6171转自:http://my.oschina.net/wolfc ... -
java 垃圾回收总结
2014-10-03 22:47 718转自:http://www.cnblogs.com/aigo ... -
java中volatile关键字的含义
2014-10-03 22:39 636转自:http://www.cnblogs.com/aigo ... -
java并发编程-Executor框架
2014-10-01 23:40 562Executor框架是指java 5中 ... -
Java中ArrayList和LinkedList区别
2014-09-17 18:48 575转自:http://pengcqu.iteye. ... -
深入理解Java内存模型之系列篇
2014-09-16 11:16 864转自:http://blog.csdn.net/ ... -
Java Thread 总结
2014-09-15 22:39 596转自:http://www.cnblogs.com/Drea ... -
如何停止一个正在运行的java线程
2014-09-15 22:33 1987转自:http://ibruce.info/2013/12 ... -
详解sleep和wait的区别
2014-09-15 22:16 2467转自:http://www.cnblogs.com/Dre ... -
Java多线程总结之由synchronized说开去
2014-09-14 13:11 657转自: http://hellosure.iteye.co ... -
ThreadLocal的正确用法
2014-09-13 23:52 501用法一:在关联数据类中创建private static ... -
Hashtable与ConcurrentHashMap差别
2014-09-06 00:00 916Hashtable与ConcurrentHashMap区别 ... -
JAVA多线程和并发基础面试问答
2014-09-01 22:56 680多线程和并发问题是Jav ... -
java 双重加锁及单例模式
2014-08-25 18:02 1160单例创建模式是一个通用的编程习语。和多线程一起使用时,必需使 ... -
Java内部类的使用小结
2014-08-13 21:45 571内部类是指在一个外部类的内部再定义一个类。类名不需要和文件夹 ... -
java sleep和wait的区别和联系
2014-08-10 20:46 663第一种解释: 功 ...
相关推荐
深入 Java 虚拟机.pdf Java 虚拟机(Java Virtual Machine,JVM)是 Java 语言的 runtime 环境,是 Java 程序执行的核心组件。它提供了一个平台无关的环境,允许 Java 程序在不同的操作系统和硬件平台上运行。 一...
《Java核心技术系列:Java虚拟机规范(Java SE 8版)》由Oracle官方发布,Java虚拟机技术创建人撰写,国内资深Java技术专家翻译。书中基于全新Java SE 8,完整且准确地阐述Java虚拟机规范,是深度了解Java虚拟机和...
Java虚拟机规范 Java SE 8版-带目录-pdf,本书完整而准确地阐释了Java虚拟机各方面的细节,围绕Java虚拟机整体架构、编译器、class文件格式、加载、链接与初始化、指令集等核心主题对Java虚拟机进行全面而深入的分析...
第1章 :简单地介绍了Java虚拟机的历史并吹捧了←_← 一下Java的平台无关性(一次编译,到处运行); 第2章:概览Java虚拟机整体架构; 第3章:介绍如何将Java语言编写的程序转换为虚拟机指令集; 第4章:定义...
本书摒弃了传统的以解读枯燥的Java虚拟机规范文档和分析繁琐的Java虚拟机源代码的方式来讲解Java虚拟机,取而代之的是,以实践的方式,引导读者如何从零开始构建和实现一个Java虚拟机,整个过程不仅能让读者做到对...
Java虚拟机(JVM)是Java程序运行的基础,它负责执行Java字节码,提供了一个与平台无关的执行环境。JVM规范定义了JVM的结构、指令集和运行时数据区,以及如何执行指令和处理异常。自1999年以来,JVM规范经历了多次...
Java虚拟机(JVM)是Java编程语言的核心组成部分,它是一种抽象的计算设备,能够运行Java字节码。Java虚拟机规范(Java SE 7版)是定义JVM行为的官方文档,确保所有Java平台的实现遵循相同的规则,以提供跨平台的...
java虚拟机规范,高清PDF版本,含有目录结构:第一章:引言; 第二章:java虚拟结构(运行时区域内存:寄存器,java虚拟机栈,java堆,方法去,运行时常量池,本地方法栈); 第三章:为java虚拟机编译; 第四章:...
Java虚拟机(JVM)是实现Java技术的关键组件,它为Java程序提供了一个运行环境。Java程序在编写后会被编译成一种称为字节码的中间表示形式,这种字节码可以跨平台运行,因为JVM负责将字节码转换成机器代码。JVM的...
Java虚拟机(Java Virtual Machine,简称JVM)是Java编程语言的核心组成部分,它是一个用于执行Java字节码的软件或硬件设备。Java程序在编译时并不直接转化为机器语言,而是转化为中间代码,即字节码。JVM的作用就是...
自1999年《Java虚拟机规范(第二版)》发布以来,尽管JDK在版本5时进行了重大更新,但直到2011年7月,《Java虚拟机规范(JavaSE7版)》才正式发布。这标志着JVM技术的持续演进和标准化进程的重要里程碑。随着时间...
Java虚拟机(JVM)是Java编程语言的核心组成部分,它为Java程序提供了跨平台的运行环境。Java程序在编写完成后,会被编译成字节码(.class文件),这些字节码可以在任何装有JVM的系统上运行,实现了“一次编写,到处...
Java虚拟机(JVM,Java Virtual Machine)是Java平台的核心组成部分,它负责执行Java程序,为Java代码提供了跨平台的运行环境。Java虚拟机的概念始于Sun Microsystems,现在由Oracle公司继续发展和维护。JVM的设计...
随着越来越多的第三方语言(Groovy、Scala、JRuby等)在Java虚拟机上运行,Java...《实战Java虚拟机——JVM故障诊断与性能优化》将通过200余示例详细介绍Java虚拟机中的各种参数配置、故障排查、性能监控以及性能优化。
《Java核心技术系列:Java虚拟机规范(Java SE 8版)》由Oracle官方发布,Java虚拟机技术创建人撰写,国内资深Java技术专家翻译。书中基于全新Java SE 8,完整且准确地阐述Java虚拟机规范,是深度了解Java虚拟机和...
《深入Java虚拟机(原书第2版)》,原书名《Inside the Java Virtual Machine,Second Edition》,作者:【美】Bill Venners,翻译:曹晓钢、蒋靖,出版社:机械工业出版社,ISBN:7111128052,出版日期:2003 年 9 ...
本书摒弃了传统的以解读枯燥的Java虚拟机规范文档和分析繁琐的Java虚拟机源代码的方式来讲解Java虚拟机,取而代之的是,以实践的方式,引导读者如何从零开始构建和实现一个Java虚拟机,整个过程不仅能让读者做到对...