jit 和 jvm
如您所知,JVM(Java Virtusal Machine)使Java能够遵循“一次写入,随处运行”的范例。 JVM的核心包括以下组件:
- 堆
- 叠放
- PermGen和方法区域
- JIT编译器
- 代码缓存
堆是在应用程序代码开发阶段为您使用的每个新运算符分配内存的位置。 堆栈将存储您将在方法范围内分配的局部变量。 需要注意的一件事是,在方法范围内定义的变量将在方法完成后删除。 例如,如果在方法范围内分配了字符串,并且保证其范围属于本地范围,则该字符串将存储在堆栈中,否则将在堆中分配。
PermGen空间将存储类和方法级别的数据以及在应用程序中定义的静态变量。 方法区域实际上是PermGen空间内的区域,它将存储您的应用程序的所有方法,字段,恒定池级别的详细信息。
JIT编译器和代码缓存并存。 JVM的核心是在运行时将Java字节码解释为汇编代码。 解释可能是一个缓慢的过程,因为每次执行部分应用程序代码时,都需要在运行时将代码从字节码转换为机器码。 这就是JIT编译器起作用的地方,它的方法超级棒,然后将其存储在代码缓存中。
JIT编译器在运行时分析应用程序代码,以了解哪些方法可以归类为热门方法。 在这种情况下很热,这意味着代码片段的访问频率更高。 在很高的层次上,JIT编译器所做的是为每个执行的方法都有一个计数器,以了解其使用频率。 当计数器达到定义的阈值时,该方法将有资格由JIT编译器编译为其相应的汇编代码,然后将其存储在代码缓存中。 现在发生的事情是,每当JIT编译器遇到对那些已编译并存储在代码缓存中的方法的调用时,它将不再尝试再次解释它们,而是将使用代码缓存内可用的已编译汇编代码。 这可以提高应用程序的性能,因为使用编译后的代码比在运行时对其进行解释要快得多。
在谈论JIT编译器时,主要有两种风格,由于缺乏相关文档,我们几乎忽略了它们。 这两种类型是:
- 客户
- 服务器
使用的默认编译器将根据您所运行的计算机体系结构和JVM版本(32位或64位)而有所不同。 让我们简要地看看每个人的工作。
客户端编译器在应用程序启动时开始将字节代码编译为汇编代码。 这间接意味着您的应用程序的启动时间将大大缩短。 但是,这带来的主要缺点是代码缓存将更快地耗尽内存。 只有在您的应用程序运行了很短的时间后,才能进行大多数优化。 但是由于客户端编译器已经占用了代码缓存空间,因此您将没有空间来存储用于这些优化的汇编代码。 这就是服务器缓存出色的地方。
与客户端编译器不同,服务器编译器不会在应用程序启动时开始编译。 它将允许应用程序代码运行一段时间(通常称为预热期),此后它将开始将字节码编译为汇编代码,然后将其存储在代码缓存中。
在我的下一篇文章中,我将讨论如何真正混合和匹配客户端和服务器编译,并向您介绍一些我们很少遇到但对于提高应用程序性能至关重要的JVM标志。
翻译自: https://www.javacodegeeks.com/2014/06/a-little-bit-on-the-jvm-and-jit.html
jit 和 jvm