小谈JVM及JIT_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > 小谈JVM及JIT

小谈JVM及JIT

 2014/6/28 18:40:55  deepinmind  程序员俱乐部  我要评论(0)
  • 摘要:你或许也知道,正是JVM(JavaVirtusalMachine,Java虚拟机)使得Java成为遵循“一次编写,处处运行”的范例。JVM包括如下核心组件:堆栈持久代及方法区JIT编译器代码缓存堆是你的应用程序代码中new操作符分配内存的地方。栈存储的是你在某个方法作用域内要进行赋值的那些本地变量。有一点需要注意的是,方法作用域内所定义的变量在方法结束后将会被删除。比如说,一个String变量在方法内被赋值了,它的作用域是本地作用域,那么它将会被存储到栈里,而给它所赋的值则是存储在堆中
  • 标签:JVM
你或许也知道,正是JVM( Java Virtusal Machine,Java虚拟机)使得Java成为遵循“一次编写,处处运行”的范例。JVM包括如下核心组件:
  • 持久代及方法区
  • JIT编译器
  • 代码缓存

  • 堆是你的应用程序代码中newcaozuofu.html" target="_blank">操作符分配内存的地方。栈存储的是你在某个方法作用域内要进行赋值的那些本地变量。有一点需要注意的是,方法作用域内所定义的变量在方法结束后将会被删除。比如说,一个String变量在方法内被赋值了,它的作用域是本地作用域,那么它将会被存储到栈里,而给它所赋的值则是存储在堆中。

    持久代空间是用来存储类及方法的数据以及应用程序中定义的静态变量。方法区其实就是持久代空间中的一块区域,它将会存储所有的方法,字段,常量池的详细数据。

    JIT编译器和代码缓存密不可分。JVM核心会在运行时将Java字节码解释成汇编代码。这个解释的过程是非常缓慢的,因为每次执行你的应用程序的代码时都需要将字节码转化成机器代码。这就是JIT编译器发挥作用的地方了,它会将方法编译好然后存储到代码缓存中。

    JIT编译器会在运行时分析应用程序的代码,来识别出哪些方法可以归类为热方法。在这里热方法意味着代码段会被频繁地访问。JIT编译器给每个方法都分配一个计数器,以便统计它们的使用频率。当计数器达到预定义的阈值时,这个方法会被JIT编译器编译成对应的汇编代码,然后存储到代码缓存中。现在,当JIT需要再调用这些已经被编译好并存储到代码缓存中的方法时,它不用再去解释执行了,而是可以使用代码缓存中已编译好的汇编代码。这能提升你的应用程序的执行效率,因为使用编译好的代码要比运行时去解释要快得多。

    当提及JIT编译器时,由于缺少相关的文档,有两个主要的因素我们大多数人可能都不太了解。它们分别是:
  • Client
  • Server


  • 默认使用哪个编译器取决于对应程序运行的机器的体系结构以及JVM的版本(32位还是64位的)。我们来看下它们分别有什么作用。

    客户端编译器在应用启动的时候就会将你的字节码编译成汇编代码。这间接意味着会增加你的应用程序的启动时间。不过它最大的缺点在于你的代码缓存可能很快就会用光你的内存。很多优化只有当你的程序运行了一段时间才能够进行。不过由于客户端编译器已经占用了代码缓存的空间,你可能没有地方去存储这些优化后的汇编代码了。这就是服务端编译器要胜出的地方。

    服务端编译器不像客户端编译器那样,它不会在应用启动的时候就编译代码。它会让应用程序的代码运行一段时间(这也被称为预热阶段),然后它才会开始将字节码编译成汇编代码,最终将它们存储到代码缓存里。

    我的下一篇文章将会讨论如何可以将客户端及服务端编译给结合起来,同时还将介绍几个很少用到的JVM参数,但它们对提升应用的性能至关重要。



    原创文章转载请注明出处:http://it.deepinmind.com



    英文原文链接

    上一篇: linq读书笔记1-linq 初步 下一篇: 没有下一篇了!
    发表评论
    用户名: 匿名