zoukankan      html  css  js  c++  java
  • jvm 解释器和JIT编译器

    0 来源 https://www.bilibili.com/video/BV1PJ411n7xZ?p=112

    1 什么是解释器(interpreter),什么是jit编译器?

    2 为什么java是半编译办解释型语言?

    3 图例

    4 为什么hotspot已经内置了jit编译器了,还有需要在使用解释器执行程序?


    1 什么是解释器(interpreter),什么是jit编译器?

    • 解释器: 当java虚拟机启动时会根据预定义的规范对字节码采用逐行解释的方式执行,将每条字节码文件中的内容"翻译"为对应平台的本地机器执行执行,
      • 现状
        • 由于解释器在设计和实现上非常简单,因此除了java语言之外,还有许多高级语言同样也是基于解释器执行的比如python,perl,ruby等,但是在今天,基于解释器执行已经沦为低效的代名词,并且时常被一些c/c++程序员所调侃
        • 为了解决这个问题,jvm平台支持一种叫作即时编译(jit)的技术,即时编译的目的是为了避免函数被解释执行,是将整个函数体编译成机器码,每次函数执行时,值执行编译后的机器码即可,这种方式可以使执行效率大幅度提升
    • jit(Just in time compiler)编译器: 就是虚拟机将源代码直接编译成和本地机器平台相关的机器语言
      • 一个被多次调用的方法,或者一个方法体内部循环次数较多的循环体都可以被称之为"热点代码",因此都可以通过jit编译器编译为本地机器指令,由于这种编译方式,发生在方法执行过程中,因此也被称之为栈上替换,或简称OSR(on stack replacement)编译
      • 一个方法究竟要被调用多少此,或者一个循环体究需要执行多少此循环才可以大道这个标准,必然需要一个明确的阈值,jit编译器才会将这些"热点代码"编译为本地机器指令执行,这里主要依靠热点探测功能
      • 目前hotspot vm 所采用的热点探测方式是基于计数器的热点探测
      • 采用基于计数器的热点探测,hotspot vm将会为每一个方法都简历2个不同类型的计数器,分别为方法调用计数器和回边计数器
        • 方法调用计数器用于统计方法的调用次数,他的默认值在client模式下是1500次,在server模式下是10000次,超过这个阈值,就会触发jit编译,这个阈值可以通过虚拟机参数-XX:CompileThreshold来人为设定
        • 回边计数器则用于统计循环体的循环次数
      • 热度衰减: 在不做任何设置,方法调用计数器统计的并不是方法被调用的绝对次数,而是一个相对的执行频率,即一段时间内方法被调用的次数,当超过一定的时间限度,如果方法的调用次数仍然不足以让他提交给即时编译器,那这个方法的调用计数器就会被减少一半,这个过程称为计数器热度的衰减,而这段时间,就称为此方法统计的半衰周期,进行热度衰减的动作是在虚拟机进行垃圾收集时顺便进行的,可以使用虚拟机参数-XX:UseCounterDecay来关闭热度衰减,让方法计数器统计方法调用的绝对次数,这样只要系统运行时间足够长,绝大部分方法都会被编译成本地代码,另外可以使用-XX:CounterHalfLifeTime参数设置半衰周期的时间,单位是秒
    •  

    2 为什么java是半编译办解释型语言?

      jdk1.0时代,将java语言定位为"解释执行"还是比较准确的,再后来,java也发展出可以直接生成本地代码的编译器

      现在jvm在执行java代码的时候,通常会将解释执行和编译执行二者结合起来进行

    3 图例

      

     4 为什么hopspot已经内置了jit编译器了,还有需要在使用解释器执行程序?

      首先明确: 当程序启动后,解释器可以马上发挥作用,争取编译的时间,立即执行, 编译器要发挥作用,把代码编译成本地代码,需要一定的执行时间,但是编译为本地代码后,执行效率高

      所以: 尽管jrockit vm中程序的执行性能可能非常高效,但程序在启动时必然需要花费更长的时间来进行编译,对于服务端的应用来说,启动时间并非关注的重点,但对于那些看中启动时间的应用场景而言,或许就需要采用解释器与即时编译器并存的架构换取一个平衡点, 在此模式下,当java虚拟机启动时,解释器可以首先发挥作用,而不必等待即时编译器全部编译完成之后再执行,这样可以省去很多不必要的编译时间,随着时间的推移,编译器发挥作用,把越来越多的代码编译成本地代码,获得跟高的执行效率, 

      同时,解释执行在编译器进行激进优化不成立的时候,作为编译器的备选方案.

  • 相关阅读:
    理解javascript观察者模式(订阅者与发布者)
    Javascript异步编程之setTimeout与setInterval详解分析(一)
    Gulp.js----比Grunt更易用的前端构建工具
    requireJS对文件合并与压缩(二)
    requireJS(版本是2.1.15)学习教程(一)
    Git使用教程
    Ajax基本知识
    go语言基础之有参有返回值函数的使用
    go语言基础之函数有多个返回值
    go语言基础之函数只有一个返回值
  • 原文地址:https://www.cnblogs.com/xiaodu9499/p/13291998.html
Copyright © 2011-2022 走看看