对于吃货出身又需要保持体重的我,出门一定要带男票,因为这样就可以把见到的好吃的都买给他吃,就当是自己吃了[汗]。偶尔做梦还是会梦到自己一个角落里偷吃东西,听到有脚步声,抬起头,大哭起来:“我饿了。” 然后就这样一直哭醒。

作为程序媛,对于程序的爱好,必须高于对吃的痴迷。虽然这对于吃货而言很难,但相比减肥都不是难事,因为我已经是一名腻害的程序媛了。

我在做项目的时候,将自己所有涉及到的项目编译和运行JAVA版本都升级到了1.7。告诉其他人说:我们要好好利用JVM升级带来的免费性能福利。有人跟我说:其实服务器上是1.7啊,只是jenkins部署的时候用的1.6而已。我叹了口气,这个问题,要我详细讲的话,我可以讲上两天,以下是精简的部分。

大家都知道,JAVA官网下载下来的包安装后里面有两个文件夹,一个是JDK(Java Development Kit),这是Java语言的软件开发工具包(SDK)。另一个是JRE(Java Runtime Environment),就是JAVA的运行时环境。如果JDK的文件夹是jdk1.7.XXX,那么相应的JRE的文件夹就是jre7。所以大家提到java版本的时候,有人习惯说java1.7,但还有人习惯说java7。

JDK的文件夹里包含了JRE。所以正常服务器上只安装JDK。Windows™里会看到JRE文件夹里大多数的文件扩展名是DLL(Dynamic Link Library),这是动态链接库文件。在Windows™中,许多应用程序并不是一个完整的可执行文件,而是被分割成一些相对独立的DLL。一个应用程序可以使用多个DLL,一个DLL也可能被不同的应用程序使用。而Linux®里的JRE文件夹下因为是完整的可执行文件,所以文件数会少一些。而且Linux®一切皆文件,所以是没有扩展名的。

看了上面的两段,累了吧。我累的时候喜欢坐在路边长椅上一边喝酸奶(健康不长胖,耶!)一边看着如花的姑娘们从眼前走过。丰满的姑娘好似茶花,圆润可爱;浓妆的姑娘好似曼陀罗,美丽却有毒,让人想靠近又不敢靠太近;还有一种会让人联想到芍药的姑娘,秀丽的气质里藏不住更美的内在……

言归正传啦,jenkins部署的时候一般包含两个步骤:一个是构建(build),还有一个是部署(deploy)。部署就是扔到实际运行服务器上。构建是先将所需要的资源按照指定的链接下载到本地,然后用JDK编译。那么用低版本的JDK进行编译有什么影响呢?

因为线上是能运行的,我们就刨去兼容问题不谈,只谈性能。

JAVA的编译期包括前端编译(将.java文件变成.class文件,.class文件就是字节码文件啦);提前编译(AOT ,ahead of time compiler,直接将.java文件编译成本地机器代码);运行期编译(JIT, just in time compiler,把字节码转变成机器码)。而jenkins部署的时候只做了前端编译。

我们常用的前端编译器:部署的时候用sun的javac,BTW(by the way),javac是纯java写的,有兴趣的童鞋可以研究一下源码。开发的时候,由于笔者本人是eclipse的铁粉儿,用的是 eclipse JDT中的增量式编译器(ECJ, Eclipse Compiler for Java)。其实javac这类编译器对代码的运行效率击鼓没有任何优化(在JDK1.3之后,javac的-O优化参数就不再有意义了)。虚拟机设计团队把对性能的优化集中到了即时编译中,这样可以让那些不是javac产生的class文件也同样能享受到编译器优化带来的好处。

好吧,人家说的是对的,jenkins用1.6编译对性能没有多大影响。毕竟我大乐视人才济济,不是随便一句话就可以忽悠人家的。但是javac做了许多针对编码过程的优化措施来改善程序员的编码风格和提高编码效率。相当多新生的java语法特性,都是靠编译器的语法糖(Syntactic Sugar,对功能没有影响,更方便程序员使用的语法)来实现,而不是依赖虚拟机的底层改进来支持,可以说,java中即时编译在运行期的优化过程对于程序运行来说更重要,而前端编译器在编译期的优化过程对于程序编码来说关系更加密切。

JAVA最初是通过解释器进行解释执行的,当虚拟机发现某人方法或代码块的运行特别频繁,就会把这些代码认定为“热点代码”而将它们编译成本地机器码,并进行各种层次的优化,完成这个任务的编译器就是即时编译器。

即时编译器也有不同的版本,比较常用的是HotSpot虚拟器的C1(clientcompiler用来获取更高的编译速度),C2(servercompiler获取更好的编译质量)编译器。它是解释器和编译器并存,保留解释器的原因是,加快启动时间,立即执行,当运行环境中内存资源限制较大时,解释器可以节约内存,解释器还可以作为激进优化的编译器的“逃生门”(称为逆优化Deoptimization),而编译器能把越来越多的代码编译成遍地代码后,获取更高的执行效率。HotSpot会根据自身版本和宿主机器的性能自动选择C1还是C2,用户也可以使用-client或者-server来自行决定。用户还可以使用-Xint强制虚拟机使用解释模式,也可以使用-Xcomp强制编译模式。

JDK设计团队几乎把代码的所有优化措施都集中在了即时编译器上,所以一般来说即时编译器产生的本地代码会比Javac产生的字节码更优秀。常用的优化技术有:公共子表达式消除,数组边界检查消除,方法内联,逃逸分析。有兴趣的童鞋可以自己研究一下,面试时很加分[胜利].

最开始还提到了提前编译。提前编译与即时编译的基本思想是相同的。在程序执行前生成Java方法的本地代码,以便在程序运行时直接使用本地代码。目的在于避免即时编译器的运行时性能消耗或内存消耗,或者避免解释程序的早期性能开销。

有人喜欢拿JAVA和C/C++对比。早期的Java运行时所提供的性能级别远低于C和C++。但是即时编译的出现使得现代的JIT编译器可以产生于C或C++静态编译相当的应用程序性能。但是,JAVA在输出本地代码上还是有一些劣势。首先,因为即时编译器运行占用的是用户程序的运行时间,具有很大的时间压力,优化手段也严重受制于编译成本。其次,Java语言是动态的类型安全语言,需要由虚拟机来确保程序不会违反语言的寓意或者访问非结构化内存。第三,Java语言中虽然没有virtual关键字,但是使用虚方法(多态方法)的频率却远远大于C和C++语言。这意味着运行时对方法接受者进行多态选择的频率要远远大于C和C++语言,这加大的优化难度。第四,Java语言是可以动态扩展的语言,运行时加载新的类可能改变程序类型的继承关系,编译器不得不时刻注意并随着类型的变化而在运行时撤销或重新进行一些优化。第五,Java语言中对象的内存分配都是在堆上进行的,只有方法中的局部变量才能在栈上分配。但是Java语言的这些性能上的劣势都是为了换取开发效率上的优势,动态安全,动态扩展,垃圾回收这些特性都为Java语言的开发效率做出了很大的贡献。

小知识:聪明的你已经注意到了文章中Windows™和Linux®的角标。™是trade mark(商业标记)的缩写。表示此商标正在受理注册中,还没有取得商标证。®表示商标已经注册并取得了商标证。

建议:大家在用英文简写的时候把简写表示的意思都解释一下,因为一个简写有很多意思,读者们需要用很长的反射弧才能想明白。

请一定记得升级java虚拟机的更多相关文章

  1. 实战Java虚拟机之三“G1的新生代GC”

    今天开始实战Java虚拟机之三:“G1的新生代GC”. 总计有5个系列 实战Java虚拟机之一“堆溢出处理” 实战Java虚拟机之二“虚拟机的工作模式” 实战Java虚拟机之三“G1的新生代GC” 实 ...

  2. 实战Java虚拟机之二“虚拟机的工作模式”

    今天开始实战Java虚拟机之二:“虚拟机的工作模式”. 总计有5个系列 实战Java虚拟机之一“堆溢出处理” 实战Java虚拟机之二“虚拟机的工作模式” 实战Java虚拟机之三“G1的新生代GC” 实 ...

  3. Java虚拟机垃圾回收(三) 7种垃圾收集器

    Java虚拟机垃圾回收(三) 7种垃圾收集器 主要特点 应用场景 设置参数 基本运行原理 在<Java虚拟机垃圾回收(一) 基础>中了解到如何判断对象是存活还是已经死亡?在<Java ...

  4. Java虚拟机垃圾回收(三): 7种垃圾收集器(转载)

    1.垃圾收集器概述 垃圾收集器是垃圾回收算法(标记-清除算法.复制算法.标记-整理算法.火车算法)的具体实现,不同商家.不同版本的JVM所提供的垃圾收集器可能会有很在差别,本文主要介绍HotSpot虚 ...

  5. 《Java虚拟机原理图解》4.JVM机器指令集

    0. 前言 Java虚拟机和真实的计算机一样,执行的都是二进制的机器码:而我们将.java 源码编译成.class 文件,class文件便是Java虚拟机可以认识的二进制机器码,Java可以识别cla ...

  6. 《java虚拟机》汇总所有关键要点

    一  .java虚拟机底层结构详解 我们知道,一个JVM实例的行为不光是它自己的事,还涉及到它的子系统.存储区域.数据类型和指令这些部分,它们描述了JVM的一个抽象的内部体系结构,其目的不光规定实现J ...

  7. 《深入理解Java虚拟机》第2版挖的坑终于在第3版中被R大填平了

    这是why技术的第34篇原创文章 本周还是在家办公的一周,上面的图就是我在家的工位,和上周<Dubbo Cluster集群那点你不知道的事>这篇文章里面的第一张图片比起来,升级了显示器支撑 ...

  8. 《深入理解Java虚拟机》第 3 版里面到底多了哪些知识点?本文竟然得到了本书作者的认可!

    这是why的第 47 篇原创文章 荒腔走板 大家好,我是 why.老规矩,先是简短的荒腔走板聊聊生活. 上面的图是前几天拍的,那天晚上下班后,刚刚走进小区就看到了这一轮弯月和旁边那一颗特别特别亮的星星 ...

  9. 《深入理解Java虚拟机》类文件结构

    上节学习回顾 在上一节当中,主要以自己的工作环境简单地介绍了一下自身的一些调优或者说是故障处理经验.所谓百变不离其宗,这个宗就是我们解决问题的思路了. 本节学习重点 在前面几章,我们宏观地了解了虚拟机 ...

随机推荐

  1. Node - EJS模板应用(node+express+ejs)

    准备工作: 工具:Webstorm 1. 新建一个文件夹为blogs(随意). 一个js文件app.js. 一个文件夹views,文件夹内一个index.ejs文件,文件夹asstes内style.c ...

  2. html5表单和伪类

    type = "email"; 自带验证格式type = "url"; 网址 http//:type = "tel";移动端会变成数字键盘t ...

  3. ArcObjects与ArcEngine的联系与区别

    ArcObjects与ArcEngine的联系与区别 AO一般指的是桌面产品开发组件,需要在桌面环境中才能够使用,最典型的就是嵌入式VBA开发.但是这样带来的弊端和OFFICE等相关软件一样明显,就是 ...

  4. Ubuntu下搭建FTP服务器

    Ubuntu下搭建FTP服务器 我装的服务器系统是Ubuntu 12.04 LTS,FTP软件当然是选择大名鼎鼎的vsftpd(very secure FTP daemon), 用系统自带的FTP还好 ...

  5. 图片转换PDF

    组件在我的文件里,需要的可以找找. public partial class MainForm : Form { private string srcFile, destFile; bool succ ...

  6. Unity3d场景漫游---iTween实现

    接触U3D以来,我做过的场景漫游实现方式一般有以下几种: Unity3d中的Animation组件,通过设置摄像机的关键点实现场景漫游 第一人称或第三人称控制器 编写摄像机控制脚本 iTween iT ...

  7. ERP实施顾问工作中应努力做到哪些?

    1.树立并分享信誉 准确的为自己定位,并积极树立自己的信誉.从这样两个角度去考虑问题,一是从高层管理者的角度去思考行业竞争和公司运作的问题,一是从专业.细致的角度去考虑单据.报表.界面等数据处理的问题 ...

  8. 如何垂直居中<img>?

    方法1: 父元素设置height=line-height,子元素设置vertical-align:middle; 方法2: 父元素display:table-cell;vertical-align:m ...

  9. 类中的两大类(string类、math类)的应用

    类是我们在学习C#的过程中很关键也是特别容易让人蒙逼得地方,类的应用直接可以调用它的属性和方法来进行判断和验证 string类(也叫字符串类) C#中的String类很有用,下面是一些它的常用方法的总 ...

  10. Struts2之Result详解

    上一篇我们把Struts2中的Action接收参数的内容为大家介绍了,本篇我们就一起来简单学习一下Action的4种Result type类型,分为:dispatcher(服务端页面跳转):redir ...