JVM以及JIT
你或许也知道,正是JVM( Java Virtusal Machine,Java虚拟机)使得Java成为遵循“一次编写,处处运行”的范例。JVM包括如下核心组件:
- 堆
- 栈
- 持久代及方法区
- JIT编译器
- 代码缓存
堆是你的应用程序代码中new操作符分配内存的地方。栈存储的是你在某个方法作用域内要进行赋值的那些本地变量。有一点需要注意的是,方法作用域内所定义的变量在方法结束后将会被删除。比如说,一个String变量在方法内被赋值了,它的作用域是本地作用域,那么它将会被存储到栈里,而给它所赋的值则是存储在堆中。
持久代空间是用来存储类及方法的数据以及应用程序中定义的静态变量。方法区其实就是持久代空间中的一块区域,它将会存储所有的方法,字段,常量池的详细数据。
JIT编译器和代码缓存密不可分。JVM核心会在运行时将Java字节码解释成汇编代码。这个解释的过程是非常缓慢的,因为每次执行你的应用程序的代码时都需要将字节码转化成机器代码。这就是JIT编译器发挥作用的地方了,它会将方法编译好然后存储到代码缓存中。
JIT编译器会在运行时分析应用程序的代码,来识别出哪些方法可以归类为热方法。在这里热方法意味着代码段会被频繁地访问。JIT编译器给每个方法都分配一个计数器,以便统计它们的使用频率。当计数器达到预定义的阈值时,这个方法会被JIT编译器编译成对应的汇编代码,然后存储到代码缓存中。现在,当JIT需要再调用这些已经被编译好并存储到代码缓存中的方法时,它不用再去解释执行了,而是可以使用代码缓存中已编译好的汇编代码。这能提升你的应用程序的执行效率,因为使用编译好的代码要比运行时去解释要快得多。
当提及JIT编译器时,由于缺少相关的文档,有两个主要的因素我们大多数人可能都不太了解。它们分别是:
- Client
- Server
默认使用哪个编译器取决于对应程序运行的机器的体系结构以及JVM的版本(32位还是64位的)。我们来看下它们分别有什么作用。
客户端编译器在应用启动的时候就会将你的字节码编译成汇编代码。这间接意味着会增加你的应用程序的启动时间。不过它最大的缺点在于你的代码缓存可能很快就会用光你的内存。很多优化只有当你的程序运行了一段时间才能够进行。不过由于客户端编译器已经占用了代码缓存的空间,你可能没有地方去存储这些优化后的汇编代码了。这就是服务端编译器要胜出的地方。
服务端编译器不像客户端编译器那样,它不会在应用启动的时候就编译代码。它会让应用程序的代码运行一段时间(这也被称为预热阶段),然后它才会开始将字节码编译成汇编代码,最终将它们存储到代码缓存里。
http://it.deepinmind.com/jvm/2014/06/28/a-little-bit-on-jvm-and-jit.html
文章来源: gamwatcher.blog.csdn.net,作者:香菜聊游戏,版权归原作者所有,如需转载,请联系作者。
原文链接:gamwatcher.blog.csdn.net/article/details/35573341
- 点赞
- 收藏
- 关注作者
评论(0)