4.1 JIT概览

  语言根据执行的方式不同分为编译型语言和解释型语言。以C++为代表的编译型语言在执行前需要编译成机器码,不同的CPU需要不同的编译器,编译成功后在同一台机器不需再次编译。以Python为代表的解释型语言,解释器一行一行的解释执行Python代码。

  编译型语言的优势在于跨平台,只要平台能够提供相应的解释器都可以执行Python代码。其缺点在于效率,比如对于循环,每次循环都要重新解释执行,而对于编译型代码在循环开始前编译一次无需再次编译。

编译器的优化

  编译器在编译语言的时候需要一定优化,优化的结果是编写的代码和机器码是不同的。优化的目的是更好的利用CPU,降低CPU等待时间。优化的副作用是会在并发编程中带来可见问题。编译器一个重要优化是从内存里取变量优化成从CPU缓存或寄存器里取变量(volatile的味道)。

  

  按理来说sum的值应该在内存里,然后每次计算的时候从内存读到寄存器,然后累加完成写回去。但如果编译器在一开始把sum放到寄存器里,累加完成后写回内存,这样和内存交互只有一次。当然,这种编译器的优化带来的是并发编程的无尽问题。

Java是怎么搞的

  Java走的是中间路线。javac把java代码编译成字节码,虚拟机解释执行字节码,并在解释执行的过程中把热点代码编译成汇编语言。由于编译的过程是在运行字节码过程中,所以被称为JIT,just in time,即使编译。

为什么不直接编译呢?

  • 如果一段代码只执行一次,编译的时间会大于解释执行的时间,所以只有那些反复执行的代码才有编译的必要,这些反复执行的代码被称为HotSpot。也只有在代码文件执行一定次数后,才能发现哪些代码是hotspot,这也是Java不直接编译的原因。
  • 一段代码执行的次数越多,编译的时候优化的结果就越好。比如java编译成class文件的时候是没有连接这一步的,所有的引用都是符号引用,需要在运行的时候判断真正引用地址。在多次执行代码的过程中能够发现一个符号引用总是指向某一物理地址,那么就可以在编译的时候直接把符号引用编译成物理地址,无需在运行的时候动态确定。

4.2 Client Server选择

  JVM启动参数,区别在于执行class文件时编译的时机不同。

  • client编译代码更早,编译器的优化更少,所以编译的类更多、质量更差。
  • server编译代码晚,编译后的代码“质量”更高,运行更快。

  为什么要这样?

  • 客户端程序生存周期短,需要加载的类较少,代码较为简单,更适合解释执行。而Server端程序复杂,运行时间更久,所以更晚质量更高的编译收获更大。
  • 客户端对启动时间更敏感。

 分层编译

  把server client统一起来的一种编译技术,在程序刚刚启动的时候使用client编译,等到程序热起来再切换成server。java8中默认开启分层编译。

4.4 与编译有关的虚拟机参数

  编译器缓存

  编译好的代码需要在JVM里缓存起来,当缓存被填满的时候就无法继续编译后续的热点代码。需要根据业务合理的提高该值。

  • -XX:ReservedCodeCacheSize 缓存最大值
  • -XX:initialCodeCacheSize 缓存初始值

  缓存从初始值开始分配符,最大分配到最大值。

  值得注意的是分层编译缓存很容易超出上限,尤其在Java7。

第4章 JIT编译器的更多相关文章

  1. JIT编译器

    深入理解Java Class文件格式(九) http://blog.csdn.net/zhangjg_blog/article/details/22432599 http://blog.csdn.ne ...

  2. 《Java性能权威指南》笔记----JIT编译器

    概览 编译型语言(C++,Fortran等):运行程序前,需要用编译器将代码静态编译成CPU可执行的汇编码.汇编码针对特定的CPU. 优点:只需编译一次,且有足够的程序信息来优化汇编码.执行速度快: ...

  3. 谈谈JIT编译器和本机影像生成器(NGen.exe)

    前言 在看<CLR>的时候,作者在开篇的时候提到了NGen.exe,前面一节执行程序集的代码中提到:程序或方法执行前会执行MSCorEE.dll中的JIT函数把要执行方法的IL转换成本地的 ...

  4. 浅谈对JIT编译器的理解。

    1. 什么是Just In Time编译器? Hot Spot 编译 当 JVM 执行代码时,它并不立即开始编译代码.这主要有两个原因: 首先,如果这段代码本身在将来只会被执行一次,那么从本质上看,编 ...

  5. NET基础课--JIT编译器如何工作1

    1..Net运行时调用JIT编译器,用来把由C#编译器生成的IL指令编译成机器代码.这一任务在应用程序的运行期间是分步进行的.JIT并不是在程序一开始就编译整个应用程序,取而代之的是,CLR是一个函数 ...

  6. JIT编译器技术理解

    参考链接: https://blog.csdn.net/liaodehong/article/details/51605457 https://www.cnblogs.com/insistence/p ...

  7. 五、CLR加载程序集代码时,JIT编译器对性能的产生的影响

    1.CLR首次加载代码造成的性能损失 四.CLR执行程序集中代码介绍了CLR在首次执行一个类的时,会初始化一个内部结构,然后当目标方法被首次调用时,JITComplier函数(JIT编译器)会验证IL ...

  8. 第一章-Javac编译器介绍

    1.Javac概述 编译器可以将编程语言的代码转换为其他形式,如Javac,将Java语言转换为虚拟机能够识别的.class文件形式.而这种将java源代码(以.java做为文件存储格式)转换为cla ...

  9. 深入浅出 JIT 编译器

    转载 https://www.ibm.com/developerworks/cn/java/j-lo-just-in-time/ JIT 编译器在运行程序时有两种编译模式可以选择,并且其会在运行时决定 ...

随机推荐

  1. Shell脚本自动重启Java服务

    话不多说直接上代码: cd /home/javaProduct/if [ -d '/home/javaProduct/lib_new/' ]; thenecho 'Has New Lib!'echo ...

  2. java(集合框架)(转)

    前言 集合①只能存放对象,存放基本类型会自动转成对应的对象②可以存放不同类型的对象(如果不使用泛型的话),且不限数量③集合中存放的只是对象的引用 集合详解 集合-1.png 集合-2.png   It ...

  3. PHP 自动加载类

    类的自动加载 (Autoloading Classes) 在编写面向对象(OOP) 程序时,很多开发者为每个类新建一个 PHP 文件. 这会带来一个烦恼:每个脚本的开头,都需要包含(include)一 ...

  4. Scala里面的排序函数的使用

    排序方法在实际的应用场景中非常常见,Scala里面有三种排序方法,分别是: sorted,sortBy ,sortWith 分别介绍下他们的功能: (1)sorted 对一个集合进行自然排序,通过传递 ...

  5. get请求utf-8解码

    package utils;import java.io.UnsupportedEncodingException;import java.net.URLDecoder; /*** <p> ...

  6. [转]Ubuntu 上创建常用磁盘阵列

    链接地址:https://www.jianshu.com/p/9a458510593a

  7. HTML布局排版之制作个人网站的文章列表

    文章列表.博文列表,一般是有文章名字和时间构成的,文章名字后面是时间,点击文章的名字,可进入该文章.为了美观,一般文章名字都有一定的最大字数限制,长宽对齐,等长宽的统一格式比较美观,这种用表格来做比较 ...

  8. 【Leetcode_easy】1042. Flower Planting With No Adjacent

    problem 1042. Flower Planting With No Adjacent 参考 1. Leetcode_easy_1042. Flower Planting With No Adj ...

  9. Selenium WebDriver原理

    WebDriver原理 WebDriver是按照Server-Client的经典设计模式设计的. Server端就是RemoteServer,可以是任意的浏览器,当我们的脚本启动浏览器后,该浏览器就是 ...

  10. SQL在线自助查询

    数据的日常查询统计分析是高频的需求,然而生产数据库由于安全.管理等方面的要求,仅仅对部分人员开发,例如DBA,总监等, 其他人员都要通过DBA才能查询数据,十分不便. 为了让DBA免于日常繁琐的工作, ...