[转帖]深入JVM - Code Cache内存池
深入JVM - Code Cache内存池
1. 本文内容
本文简要介绍JVM的 Code Cache(本地代码缓存池)。
2. Code Cache 简要介绍
简单来说,JVM会将字节码编译为本地机器码,并使用 Code Cache 来保存。
每一个可执行的本地代码块,称为一个 nmethod。
nmethod 可能对应一个完整的Java方法,或者是内联后的方法。
即时编译器(just-in-time,JIT)是代码缓存区的最大消费者,所以此区域又被开发者称为 JIT code cache。
3. 对 Code Cache 进行调优
code cache 区域的大小是固定的。
如果Code Cache区域用满了,就会停止JIT编译, 也就是说JVM不再编译任何代码。
我们还会收到 “CodeCache is full… The compiler has been disabled” 之类的告警消息。
JIT编译器关闭的结果,就是系统性能急剧下降。
为了避免这种情况,我们需要对Code Cache进行调优,例如使用以下参数:
InitialCodeCacheSize- 初始大小, 默认值为160KBReservedCodeCacheSize- 保留给Code Cache的空间, 也就是最大空间, 默认值:48MBCodeCacheExpansionSize- 每次扩充的大小, 一般为32KB或者64KB
合理地增加 ReservedCodeCacheSize 是一种解决办法, 毕竟现在很多应用加上依赖库的代码量一点都不少。
但我们也不能无限制地增大这个区域的大小。
幸运的是,JVM提供了一个启动参数 UseCodeCacheFlushing, 用来控制Code Cache的刷新。 这个参数的默认值为 false。
如果将其开启(-XX:+UseCodeCacheFlushing),则会在满足以下条件时释放占用的区域:
- code cache用满; 如果该区域的大小超过某个阈值,则会刷新。
- 自上次清理后经过了一定的时间间隔。
- 预编译的代码不够热。 对于每个JIT编译的方法,JVM都会有一个热度跟踪计数器。 如果计数器的值小于动态阈值,则JVM会释放这段预编译的代码。
提示: 除非Code Cache不够用了,否则不要乱开;
4. 查看Code Cache的使用情况
想要监控代码缓存的使用情况,我们可以跟踪当前使用的内存大小。
指定JVM启动参数: -XX:+PrintCodeCache, 会打印Code Cache区的使用情况。
程序执行过程中, 我们可以看到类似下面的输出:
$ java -XX:+PrintCodeCache -XX:+UseCodeCacheFlushing -version
CodeCache: size=245760Kb used=1060Kb max_used=1071Kb free=244699Kb
- 1
- 2
- 3
一起来分析下各个部分数值的含义:
size表示此内存区域的最大值,与ReservedCodeCacheSize相等。used是此区域当前实际使用的内存大小。max_used是程序启动以来的历史最大使用量free是此区域尚未使用的空闲空间
PrintCodeCache 选项非常有用,可以帮助我们:
- 查看何时进行了刷新(flushing)
- 确定内存使用量是否达到关键点位
5. Code Cache分段
从Java 9开始,JVM将 Code Cache 细分为三个不同的段,每个段包含一种类型的编译代码。
具体是:
- 非方法段(non-method segment), 保存相关的JVM内部代码,例如字节码解释器。 默认情况下,此段约为
5 MB。 可通过-XX:NonNMethodCodeHeapSize参数进行调整。 - 待分析代码段(profiled-code segment), 包含经过简单优化的代码,使用寿命很短。 此段的大小默认为
122 MB,可以通过-XX:ProfiledCodeHeapSize参数进行调整。 - 静态代码段(non-profiled segment), 保存经过全面优化的本地代码,使用寿命可能很长。 默认大小同样是
122 MB。 可以通过-XX:NonProfiledCodeHeapSize参数进行调整。
这种新的分段结构,以不同方式处理各种类型的编译代码,整体上具有更好的性能。
例如,将已编译的短命代码和长寿代码分开,提高方法清除器的性能 - 毕竟需要扫描的内存区域变小了。
6. 小结
本文简要介绍了JVM的Code Cache内存区域。
也介绍了一些监视和诊断此内存区使用情况的方法,以及相关的优化和配置选项。
- 原文链接: https://www.baeldung.com/jvm-code-cache
- GitHub双语对照版: https://github.com/cncounter/translation/tree/master/tiemao_2020/21_jvm-code-cache (路过的小伙伴, 请点小星星Star支持)
[转帖]深入JVM - Code Cache内存池的更多相关文章
- JVM Code Cache空间不足,导致服务性能变慢
本文阅读时间大约5分钟. 有业务反馈,线上一个应用运行了一段时间之后,在高峰期之后,突然发现处理能力下降,接口的响应时间变长,但是看Cat上的GC数据,一切都很正常. 通过跳板机上机器查看日志,发现一 ...
- [转帖]Linux中buff/cache内存占用过高解决办法
Linux中buff/cache内存占用过高解决办法 https://www.cnblogs.com/rocky-AGE-24/p/7629500.html /proc/sys/vm/drop_cac ...
- JVM内存区域详解(Eden Space、Survivor Space、Old Gen、Code Cache和Perm Gen)
JVM区域总体分两类,heap区和非heap区.heap区又分为: Eden Space(伊甸园). Survivor Space(幸存者区). Old Gen(老年代). 非heap区又分: Cod ...
- JVM虚拟机20:内存区域详解(Eden Space、Survivor Space、Old Gen、Code Cache和Perm Gen)
1.内存区域划分 根据我们之前介绍的垃圾收集算法,限定商用虚拟机基本都采用分代收集算法进行垃圾回收.根据对象的生命周期的不同将内存划分为几块,然后根据各块的特点采用最适当的收集算法.大批对象死去.少量 ...
- [转帖]JVM—深入理解内存模型与垃圾收集机制
JVM—深入理解内存模型与垃圾收集机制 https://juejin.im/post/5d68dc9ee51d4561ad6548f7 前言 Java是一种跨平台的语言,当初其设计初衷也是为了解决各个 ...
- JVM:查看java内存情况命令
jmap (linux下特有,也是很常用的一个命令) 观察运行中的jvm物理内存的占用情况. 参数如下: -heap :打印jvm heap的情况 -histo: 打印jvm heap的直方图.其输出 ...
- 【JVM】Java内存模型
原文:多线程之Java内存模型(JMM)(一) 概述 多任务和高并发是衡量一台计算机处理器的能力重要指标之一.一般衡量一个服务器性能的高低好坏,使用每秒事务处理数(Transactions Per S ...
- 感悟优化——Netty对JDK缓冲区的内存池零拷贝改造
NIO中缓冲区是数据传输的基础,JDK通过ByteBuffer实现,Netty框架中并未采用JDK原生的ByteBuffer,而是构造了ByteBuf. ByteBuf对ByteBuffer做了大量的 ...
- 基础篇:JVM运行时内存布局
目录 1 JVM的内存区域布局 2 JVM五大数据区域介绍 3 JVM运行时内存布局和JMM内存模型区别 4 JMM内存模型交互操作 欢迎指正文中错误 关注公众号,一起交流 参考文章 1 JVM的内存 ...
- JVM探秘1--JVM内存运行时区域划分
Java程序员一般不需要太关注内存,因为操作内存的权力都交给了Java虚拟机,但是Java程序员必须需要了解JVM是如何使用内存的,否则一旦内存出现泄漏或事溢出的话,就会一筹莫展不知道从哪去入手排查问 ...
随机推荐
- 一文带你深入理解K8s-Pod的意义和原理
本文分享自华为云社区<深入理解K8s-Pod的意义和原理>,作者:breakDawn. 在Kubernetes概念中,有以下五种概念: 容器container:镜像管理的最小单位 生产任务 ...
- 【scikit-learn基础】--『监督学习』之 逻辑回归分类
逻辑回归这个算法的名称有一定的误导性.虽然它的名称中有"回归",当它在机器学习中不是回归算法,而是分类算法.因为采用了与回归类似的思想来解决分类问题,所以它的名称才会是逻辑回归. ...
- Docker安装 配置
Docker的技术原理: 1. Linux 命名空间(Namespaces) 进程命名空间:使得每个容器拥有独立的进程空间,互相隔离,不受其他容器影响. 网络命名空间:提供独立的网络栈,每个容器有自己 ...
- 面试官:禁用Cookie后Session还能用吗?
Cookie 和 Session 是 Web 应用程序中用于保持用户状态的两种常见机制,它们之间既有联系也有区别. Cookie 是由服务器在 HTTP 响应中发送给客户端(通常是浏览器)的一小段数据 ...
- C++ 惯用法之 RAII
RAII(Resource Acquisition Is Initialization)资源获取即初始化,是 C++ 中最基本.应用最广范的惯用法(idiom)之一. RAII 的基本思想是通过构造/ ...
- MySQL进阶篇:详解索引分类和索引语法
MySQL进阶篇:第二章_二.三_ 索引分类和索引语法 索引分类 在MySQL数据库,将索引的具体类型主要分为以下几类:主键索引.唯一索引.常规索引.全文索引. 分类 含义 特点 关键字 主键索引 针 ...
- GaussDB技术解读系列之应用无损透明(ALT)
本文作者 :华为云GaussDB研发高级工程师 藏琦 1.背景 GaussDB作为一款企业级分布式数据库,提供了"同城跨AZ双活.两地三中心.双集群强一致"等极致的高可用容灾能力. ...
- Go语言微服务开发框架:Go chassis
摘要:分布式系统中每个进程的动态配置管理及运行时热加载就成为了一个亟待解决的问题.go chassis汲取了netflix的archaius框架经验,并做出来自己的创新特性. 引言 https://g ...
- 毕昇 JDK:为啥是ARM 上超好用的 JDK
摘要:毕昇 JDK 是华为基于 OpenJDK 定制的开源版本,是一款高性能.可用于生产环境的 OpenJDK 发行版. 本文分享自华为云社区<[云驻共创]毕昇 JDK:"传奇再现&q ...
- 带你掌握java反序列化漏洞及其检测
摘要:在本文中将先介绍java反序列化漏洞的原理,然后在此基础上介绍安全工具如何检测.扫描此类漏洞. 本文分享自华为云社区<java反序列化漏洞及其检测>,作者: alpha1e0. 1 ...