https://juejin.im/post/5c890f21f265da2d993dc692

CodeCache是热点代码的暂存区,经过即时编译器编译的代码会放在这里,它存在于堆外内存。除了JIT编译的代码之外,Java所使用的本地方法代码(JNI)也会存在codeCache中。

JVM内部会先尝试解释执行Java字节码,当方法调用或循环回边达到一定次数时,会触发即时编译,将Java字节码编译成本地机器码以提高执行效率。这个编译的本地机器码是缓存在CodeCache中的,如果有大量的代码触发了即时编译,而且没有及时GC的话,CodeCache就会被填满。

一旦CodeCache被填满,已经被编译的代码还会以本地代码方式执行,但后面没有编译的代码只能以解释执行的方式运行。

通过第2小节的比较,可以清晰看出解释执行和编译执行的性能差异。所以对于大多数应用来说,这种情况的出现是灾难性的。

JVM针对CodeCache提供了GC方式: -XX:+UseCodeCacheFlushing。在JDK1.7.0_4之后这个参数默认开启,当CodeCache即将填满时会尝试回收。JDK7在这方面的回收做的不是很少,GC收益较低,在JDK8有了很大的改善,所以可以通过升级到JDK8来直接提升这方面的性能。

在Java8中提供了一个JVM启动参数:-XX:+PrintCodeCache,他可以在JVM停止时打印CodeCache的使用情况,可以在每次停止应用时观察一下这个值,慢慢调整为一个最合适的大小。

通过在启动参数上增加:-XX:+UseCodeCacheFlushing 来启用;

打开这个选项,在JIT被关闭之前,也就是CodeCache装满之前,会在JIT关闭前做一次清理,删除一些CodeCache的代码;

如果清理后还是没有空间,那么JIT依然会关闭。这个选项默认是关闭的;

在JDK8中,当以server模式启动时,分层编译默认开启。需要注意的是,分层编译方式只能用于server模式中,如果需要关闭分层编译,需要加上启动参数 -XX:-TieredCompilation;如果以client模式启动,-XX:+TieredCompilation 参数将会被忽略。

JIT编译器被停止了,并且不会被重新启动,此时会回归到解释执行;

被编译过的代码仍然以编译方式执行,但是尚未被编译的代码就 只能以解释方式执行了。
针对这种情况,JVM提供了一种比较激进的codeCache回收方式:Speculative flushing。

在JDK1.7.0_4之后这种回收方式默认开启,而之前的版本需要通过一个启动参数来开启:-XX:+UseCodeCacheFlushing。

在Speculative flushing开启的情况下,当codeCache将要耗尽时:

最早被编译的一半方法将会被放到一个old列表中等待回收;

在一定时间间隔内,如果old列表中方法没有被调用,这个方法就会被从codeCache充清除;

Code Cache满了时紧急进行清扫工作,它会丢弃一半老的编译代码;

Code Cache空间降了一半,方法编译工作仍然可能不会重启;

flushing可能导致高的cpu使用,从而影响性能下降;

JDK 8对codeCache的回收有了很明显的改善。不仅codeCache的增长比较平缓,而且当使用量达到75%时,回收力度明显加大,codeCache使用量在这个值上下浮动,并缓慢增长。最重要的是,JIT编译还在正常执行,系统运行速度也没有收到影响。

jvm——CodeCache的更多相关文章

  1. 微服务开源生态报告 No.8

    「微服务开源生态报告」,汇集各个开源项目近期的社区动态,帮助开发者们更高效的了解到各开源项目的最新进展. 社区动态包括,但不限于:版本发布.人员动态.项目动态和规划.培训和活动. 非常欢迎国内其他微服 ...

  2. 微服务开源生态报告 No.7

    「微服务开源生态报告」,汇集各个开源项目近期的社区动态,帮助开发者们更高效的了解到各开源项目的最新进展. 社区动态包括,但不限于:版本发布.人员动态.项目动态和规划.培训和活动. 非常欢迎国内其他微服 ...

  3. JVM Management API

    JVM本身提供了一组管理的API,通过该API,我们可以获取得到JVM内部主要运行信息,包括内存各代的数据.JVM当前所有线程及其栈相关信 息等等.各种JDK自带的剖析工具,包括jps.jstack. ...

  4. jmap之使用说明与JVM配置

    详情可参见:http://blog.csdn.net/fenglibing/article/details/6411953. 1 2. 3.vi 打开查看,具体介绍请看上述链接. 4.查看tomcat ...

  5. JVM知识点

    先发个链接到两位大牛的主页 http://rednaxelafx.iteye.com/               http://icyfenix.iteye.com/ 目录 1)概述 2)编译 3) ...

  6. [转]JVM内幕:Java虚拟机详解

    本文由 ImportNew - 挖坑的张师傅 翻译自 jamesdbloom.欢迎加入翻译小组.转载请见文末要求. 这篇文章解释了Java 虚拟机(JVM)的内部架构.下图显示了遵守Java SE 7 ...

  7. 深入理解JVM内部结构(转)

    图中显示的组件将会在下面两部分中进行逐一的解释.第一部分涉及JVM为每一个线程都会创建的组件:第二部分则是独立于线程进行创建的组件.   1. Thread       Thread是一个程序中的一个 ...

  8. JVM的相关知识整理和学习--(转载)

    JVM是虚拟机,也是一种规范,他遵循着冯·诺依曼体系结构的设计原理.冯·诺依曼体系结构中,指出计算机处理的数据和指令都是二进制数,采用存储程序方式不加区分的存储在同一个存储器里,并且顺序执行,指令由操 ...

  9. JVM内幕:Java虚拟机详解

    这篇文章解释了Java 虚拟机(JVM)的内部架构.下图显示了遵守 Java SE 7 规范的典型的 JVM 核心内部组件. 上图显示的组件分两个章节解释.第一章讨论针对每个线程创建的组件,第二章节讨 ...

随机推荐

  1. 求第n个质数

    输入一个不超过 10000 的正整数 n,求第n个质数 样例输入 10 样例输出 29 题目地址 #include<stdio.h> #include<math.h> int ...

  2. HtML5与CSS3基础

    HTML标签 1.<a></a> 超链接标签 属性 href:跳转页面的连接 name:实现定锚功能,跳转同一页面不同位置(例返回顶部) target: (self, pare ...

  3. python map 的用法

    map的用法 ——.我们来分析map在python的源码 class map(object): """ map(func, *iterables) --> map ...

  4. 微服务理论之二:面向微服务架构与传统架构、SOA对比,以及云化对比

    一.Monolith 网上对Microservice进行介绍的文章常常以Monolith作为开头,我也不会例外.原因是,知道了Monolith的不便之后才能更容易地理解Microservice架构模式 ...

  5. ubuntu18下lamp虚拟路劲配置

    一.配置二级域名 修改hosts文件,模拟dns解析. 位置:/etc/hosts 添加 127.0.0.1  myweb.service.com 二.创建项目目录 apache默认目录是/var m ...

  6. Kafka 教程(二)-安装与基础操作

    单机安装 1. 安装 java 2. 安装 zookeeper [这一步可以没有,因为 kafka 自带了 zookeeper] 3. 安装 kafka 下载链接 kafka kafka 是 scal ...

  7. 邀请好友注册页面光标点到输入框后,输入框会先灰一下。只有ios存在

    输入框会先灰一下.只有ios存在 用这一行代码可以解决问题: -webkit-tap-highlight-color:transparent;

  8. JavaSE--抽象类、内部类、接口

    一.抽象类 当事物不能具体描述时可将事物抽象化,只对其应有的行为进行简单的描述而不进行深度具体的描述,这样就产生了抽象类,使用abstract关键字对类进行修饰内部方法也是用abstract进行描述. ...

  9. [转载]Linux运行模式及紧急、救援模式

    运行模式 在Linux中,存在一个叫init(initialize)的进程,其进程号是1,该进程存在一个对应的配置文件inittab,叫做系统的运行级别配置文件,位置在/etc/inittab.(但是 ...

  10. luogu P1852 [国家集训队]跳跳棋

    luogu 直接操作是不可能的,考虑发现一些性质.可以发现如果每次跳的棋子都是两边的,那么最多只有一种方案,那么就把这样操作得到的状态记为当前状态的父亲,从一个状态这样做一定会结束.那么如果两个状态只 ...