JVM以及JIT

举报
香菜聊游戏 发表于 2021/07/15 01:54:51 2021/07/15
【摘要】 你或许也知道,正是JVM( Java Virtusal Machine,Java虚拟机)使得Java成为遵循“一次编写,处处运行”的范例。JVM包括如下核心组件: 堆栈持久代及方法区JIT编译器代码缓存 堆是你的应用程序代码中new操作符分配内存的地方。栈存储的是你在某个方法作用域内要进行赋值的那些本地变量。有一点需要注意的是,方法作用域内所定义的变量在方法结束后将会被删...

你或许也知道,正是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

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。