Java代码是如何在虚拟机中运行的

       Java作为一门高级语言,它的语法非常复杂、抽象程度也很高。想像C语言一样直接运行在硬件上显然是不可能的,所以在Java程序运行之前,需要将Java程序通过编译器转换成虚拟机所能识别的Java字节码,Java字节码都是固定的一个字节,因此只要将Java程序转换成虚拟机所能识别的Java字节码,就能做到“一次编译,到处运行”。

       是不是感觉Java虚拟机很强大,虚拟机不仅仅能将Java字节码翻译成机器码,它还有另外一个好处,就是托管环境,托管环境能够代替我们处理一些代码中冗长而且容易出错的部分。其中最广为人知的当属自动内存管理与垃圾回收。(可能自动内存管理大家没听说过,但垃圾回收机制,相信很多人都听说过),除此之外还有例如:数组越界、动态类型、安全权限等等的动态检测。

      我们都知道Java虚拟机在内存中划分为:堆、方法区、栈,三块区域,栈又分为Java方法栈、本地方法栈、以及PC寄存器,在运行过程中,每当调用进入一个Java方法,Java虚拟机就会在当前线程中的Java方法栈中生成一个栈帧,栈帧是用于存放局部变量以及字节码操作数的,栈帧的大小都是提前计算好的,而且Java虚拟机不要求栈帧在内存空间里连续分布,当退出当前执行的方法时,不管是正常返回,还是异常返回,Java虚拟机都去弹出当前线程中的当前栈帧,并将之舍弃。这一动作称之为“弹栈”。

PC寄存器( PC register ):每个线程启动的时候,都会创建一个PC(Program Counter,程序计数器)寄存器。PC寄存器里保存有当前正在执行的JVM指令的地址。 每一个线程都有它自己的PC寄存器,也是该线程启动时创建的。保存下一条将要执行的指令地址的寄存器是 :PC寄存器。PC寄存器的内容总是指向下一条将被执行指令的地址,这里的地址可以是一个本地指针,也可以是在方法区中相对应于该方法起始指令的偏移量

     上述说过,Java字节码是不可能直接在硬件中运行的,需要用虚拟机将字节码翻译成机器码,在HotSpot虚拟机(也称之为Java虚拟机)里面有两种形式的翻译:第一种是解释执行,解释执行是将字节码一条一条翻译成机器码并且执行,就是说它是翻译一条就马上执行,所以无需等待编译,第二种是即时编译(JIT编译),即时编译是将一个方法里面的所有字节码全部翻译成机器码后在一起执行,所以它的执行速度很快,HotSpot默认采用混合模式,它会先用解释执行执行字节码,当遇到反复执行的热点代码时,以方法为单位进行即时编译

点击-->热点代码详细的可以看我的转载 

  上面说到热点代码可以很多人都不懂,我这里解说下,热点代码,我个人理解为在程序中在一定的时间内重复使用的代码,叫热点代码,在HotSpot中有一个叫热点代码探测技术,这个技术是判断该代码是否为热点代码的,判断方式有两种,第一种是基于采样的热点探测,第二种是基于计数器的热点探测,采用这种方式的虚拟机会为每个方法建立一个计数器,用来统计方法的执行次数,当执行次数达到一定的值就会认为这个方法是热点代码。

    注意计数器统计的次数不是该方法的绝对执行次数,而是该方法在一定时间内的执行频率,所以当超过一定的时间期限,如果方法的调用次数仍然不足以让HotSpot认定为热点代码,那这个方法的调用计数器就会被减少一半,这个过程称为方法调用计数器的热度的衰减,而这段时间就成为此方法统计的半衰周期,进行热度衰减的动作在虚拟机进行垃圾收集时顺便进行了。

     对于不常用的代码,我们没有必要耗费时间将其转换为机器码,可以直接使用解释执行进行运行,对于热点代码我们可以直接使用即时编译进行运行,以达到最理想的运行速度。

    为了满足同用户场景的需要,HotSpot内置了多个即时编译器:C1、C2、Graal。其中Graal是Java10引入的即时编译器。C1又叫Client编译器,面向的是对启动性能有要求的客户端GUI程序,它采用的优化手段比较简单,因此编译时间也相对较短,C2又叫做Server编译器,面向的是对峰值性能有要求的服务器端程序,采用的优化手段相对复杂,因此编译时间也相对较长,但生成代码的执行效率比较高。

     从Java7开始,HotSpot默认采用分层编译的方式:热点方法会先被C1编译,而热点方法中的热点会进一步被C2编译。为了不影响程序的正常运行,即时编译是放在额外的线程中进行编译的,HotSpot会根据CPU的数量设置编译线程的数目,并按1:2的比例分配给C1和C2。

 如有不对的地方请大家指出来,我也只是个刚研究的小白,谢谢

   

 

 

      

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值