聊聊jvm的Code Cache
序
本文主要研究一下jvm的Code Cache
Code Cache
JVM生成的native code存放的内存空间称之为Code Cache;JIT编译、JNI等都会编译代码到native code,其中JIT生成的native code占用了Code Cache的绝大部分空间
相关参数
Codecache Size Options
- -XX:InitialCodeCacheSize
用于设置初始CodeCache大小
- -XX:ReservedCodeCacheSize
用于设置Reserved code cache的最大大小,通常默认是240M
- -XX:CodeCacheExpansionSize
用于设置code cache的expansion size,通常默认是64K
Codecache Flush Options
- -XX:+UseCodeCacheFlushing
是否在code cache满的时候先尝试清理一下,如果还是不够用再关闭编译,默认开启
Compilation Policy Options
- -XX:CompileThreshold
方法触发编译时的调用次数,默认是10000
- -XX:OnStackReplacePercentage
方法中循环执行部分代码的执行次数触发OSR编译时的阈值,默认是140
Compilation Limit Options
- -XX:MaxInlineLevel
针对嵌套调用的最大内联深度,默认为9
- -XX:MaxInlineSize
方法可以被内联的最大bytecode大小,默认为35
- -XX:MinInliningThreshold
方法可以被内联的最小调用次数,默认为250
- -XX:+InlineSynchronizedMethods
是否允许内联synchronized methods,默认为true
Diagnostic Options
- -XX:+PrintFlagsFinal(
默认没有启用
)
用于查看所有可设置的参数及最终值(
JDK 6 update 21开始才可以用
),默认是不包括diagnostic或experimental系的。如果要在-XX:+PrintFlagsFinal的输出里看到这两种参数的信息,分别需要显式指定-XX:+UnlockDiagnosticVMOptions / -XX:+UnlockExperimentalVMOptions(-XX:+PrintCommandLineFlags 这个参数的作用是显示出VM初始化完毕后所有跟最初的默认值不同的参数及它们的值
)
- -XX:+PrintCodeCache(
默认没有启用
)
-XX:+PrintCodeCache用于jvm关闭时输出code cache的使用情况
- -XX:+PrintCodeCacheOnCompilation(
默认没有启用
)
用于在方法每次被编译时输出code cache的使用情况
查看Code Cache的使用情况
-XX:+PrintCodeCache
CodeHeap 'non-profiled nmethods': size=120032Kb used=2154Kb max_used=2160Kb free=117877Kbbounds [0x00000001178ea000, 0x0000000117b5a000, 0x000000011ee22000]
CodeHeap 'profiled nmethods': size=120028Kb used=10849Kb max_used=11005Kb free=109178Kbbounds [0x00000001103b3000, 0x0000000110e73000, 0x00000001178ea000]
CodeHeap 'non-nmethods': size=5700Kb used=1177Kb max_used=1239Kb free=4522Kbbounds [0x000000010fe22000, 0x0000000110092000, 0x00000001103b3000]total_blobs=5638 nmethods=4183 adapters=435compilation: enabledstopped_count=0, restarted_count=0full_count=0
复制代码
- jvm启动参数加上-XX:+PrintCodeCache,可以在jvm关闭时输出code cache的使用情况
- 这里分了non-profiled nmethods、profiled nmethods、non-nmethods三部分来展示
- 其中size就是限制的最大大小,used表示实际使用量,max_used就是使用大小的high water mark,free由size-used得来
jcmd pid Compiler.codecache
/ # jcmd 1 Compiler.codecache
1:
CodeHeap 'non-profiled nmethods': size=120036Kb used=1582Kb max_used=1582Kb free=118453Kbbounds [0x00007f1e42226000, 0x00007f1e42496000, 0x00007f1e4975f000]
CodeHeap 'profiled nmethods': size=120032Kb used=9621Kb max_used=9621Kb free=110410Kbbounds [0x00007f1e3acee000, 0x00007f1e3b65e000, 0x00007f1e42226000]
CodeHeap 'non-nmethods': size=5692Kb used=1150Kb max_used=1198Kb free=4541Kbbounds [0x00007f1e3a75f000, 0x00007f1e3a9cf000, 0x00007f1e3acee000]total_blobs=5610 nmethods=4369 adapters=412compilation: enabledstopped_count=0, restarted_count=0full_count=0
复制代码
使用jcmd的Compiler.codecache也可以查看code cache的使用情况,输出跟-XX:+PrintCodeCache相同
jcmd pid VM.native_memory
/ # jcmd 1 VM.native_memory
1:Native Memory Tracking:Total: reserved=1928023KB, committed=231182KB
- Java Heap (reserved=511488KB, committed=140288KB)(mmap: reserved=511488KB, committed=140288KB)- Class (reserved=1090832KB, committed=46608KB)(classes #8218)( instance classes #7678, array classes #540)(malloc=1296KB #19778)(mmap: reserved=1089536KB, committed=45312KB)( Metadata: )( reserved=40960KB, committed=39680KB)( used=38821KB)( free=859KB)( waste=0KB =0.00%)( Class space:)( reserved=1048576KB, committed=5632KB)( used=5190KB)( free=442KB)( waste=0KB =0.00%)- Thread (reserved=37130KB, committed=2806KB)(thread #36)(stack: reserved=36961KB, committed=2636KB)(malloc=127KB #189)(arena=42KB #70)- Code (reserved=248651KB, committed=15351KB)(malloc=963KB #4600)(mmap: reserved=247688KB, committed=14388KB)- GC (reserved=21403KB, committed=7611KB)(malloc=5419KB #9458)(mmap: reserved=15984KB, committed=2192KB)- Compiler (reserved=150KB, committed=150KB)(malloc=20KB #447)(arena=131KB #5)- Internal (reserved=3744KB, committed=3744KB)(malloc=1696KB #6416)(mmap: reserved=2048KB, committed=2048KB)- Other (reserved=24KB, committed=24KB)(malloc=24KB #2)- Symbol (reserved=10094KB, committed=10094KB)(malloc=7305KB #219914)(arena=2789KB #1)- Native Memory Tracking (reserved=4130KB, committed=4130KB)(malloc=12KB #158)(tracking overhead=4119KB)- Arena Chunk (reserved=177KB, committed=177KB)(malloc=177KB)- Logging (reserved=7KB, committed=7KB)(malloc=7KB #264)- Arguments (reserved=18KB, committed=18KB)(malloc=18KB #500)- Module (reserved=165KB, committed=165KB)(malloc=165KB #1699)- Safepoint (reserved=4KB, committed=4KB)(mmap: reserved=4KB, committed=4KB)- Unknown (reserved=4KB, committed=4KB)(mmap: reserved=4KB, committed=4KB)
复制代码
使用jcmd的VM.native_memory也可以查看code cache的使用情况(
Code部分
),Compiler部分为Memory tracking used by the compiler when generating code
使用MemoryPoolMXBean查看
@Testpublic void testGetCodeCacheUsage(){ManagementFactory.getPlatformMXBeans(MemoryPoolMXBean.class).stream().filter(e -> MemoryType.NON_HEAP == e.getType()).filter(e -> e.getName().startsWith("CodeHeap")).forEach(e -> {LOGGER.info("name:{},info:{}",e.getName(),e.getUsage());});}
复制代码
MemoryPoolMXBean包含了HEAP及NON_HEAP,其中code cache属于NON_HEAP,其输出如下:
12:21:10.728 [main] INFO com.example.CodeCacheTest - name:CodeHeap 'non-nmethods',info:init = 2555904(2496K) used = 1117696(1091K) committed = 2555904(2496K) max = 5836800(5700K)
12:21:10.743 [main] INFO com.example.CodeCacheTest - name:CodeHeap 'profiled nmethods',info:init = 2555904(2496K) used = 1543808(1507K) committed = 2555904(2496K) max = 122908672(120028K)
12:21:10.743 [main] INFO com.example.CodeCacheTest - name:CodeHeap 'non-profiled nmethods',info:init = 2555904(2496K) used = 319616(312K) committed = 2555904(2496K) max = 122912768(120032K)
复制代码
spring boot应用查看
/ # curl -i "http://localhost:8080/actuator/metrics/jvm.memory.used?tag=area:nonheap"
HTTP/1.1 200
Content-Disposition: inline;filename=f.txt
Content-Type: application/vnd.spring-boot.actuator.v2+json;charset=UTF-8
Transfer-Encoding: chunked
Date: Sat, 30 Mar 2019 04:26:39 GMT{"name":"jvm.memory.used","description":"The amount of used memory","baseUnit":"bytes","measurements":[{"statistic":"VALUE","value":6.5295408E7}],"availableTags":[{"tag":"id","values":["CodeHeap 'non-profiled nmethods'","CodeHeap 'profiled nmethods'","Compressed Class Space","Metaspace","CodeHeap 'non-nmethods'"]}]}/ # curl -i "http://localhost:8080/actuator/metrics/jvm.memory.used?tag=area:nonheap&tag=id:CodeHeap%20%27non-profiled
%20nmethods%27"
HTTP/1.1 200
Content-Disposition: inline;filename=f.txt
Content-Type: application/vnd.spring-boot.actuator.v2+json;charset=UTF-8
Transfer-Encoding: chunked
Date: Sat, 30 Mar 2019 04:24:58 GMT{"name":"jvm.memory.used","description":"The amount of used memory","baseUnit":"bytes","measurements":[{"statistic":"VALUE","value":1592448.0}],"availableTags":[]}
复制代码
springboot使用micrometer,通过/actuator/metrics接口提供相关指标查询功能,其中code cache在jvm.memory.used这个metric中 它是基于MemoryPoolMXBean来实现的,具体详见micrometer-core-1.1.3-sources.jar!/io/micrometer/core/instrument/binder/jvm/JvmMemoryMetrics.java
小结
- JVM生成的native code存放的内存空间称之为Code Cache;JIT编译、JNI等都会编译代码到native code,其中JIT生成的native code占用了Code Cache的绝大部分空间
- -XX:ReservedCodeCacheSize用于设置Reserved code cache的最大大小,通常默认是240M;对于有些应用来说240M可能太大,code cache可能都填不满,相当于unconstrained,此时JIT就会继续编译任何它认为可以编译的code
- 查看Code Cache的内存使用情况有好几种方法:
- jvm启动参数加上-XX:+PrintCodeCache,可以在jvm关闭时输出code cache的使用情况
- 使用jcmd的Compiler.codecache,其输出跟-XX:+PrintCodeCache相同;
- 使用jcmd的VM.native_memory也可以查看code cache的使用情况(
Code部分
) - 使用JMX来获取NON_HEAP类型中的name为CodeHeap开头的MemoryPoolMXBean可以得到code cache的使用情况
- 如果是springboot应用,它使用micrometer,通过/actuator/metrics接口提供相关指标查询功能,其中code cache在jvm.memory.used这个metric中
doc
- 15 Codecache Tuning
- JVM的编译策略
- What are ReservedCodeCacheSize and InitialCodeCacheSize?
- Why does the JVM have a maximum inline depth?
- Code Cache满导致应用性能降低
转载于:https://juejin.im/post/5c9ef81151882567e7055260
聊聊jvm的Code Cache相关推荐
- JVM内存区域详解(Eden Space、Survivor Space、Old Gen、Code Cache和Perm Gen)
参考文章: https://www.cnblogs.com/redcreen/archive/2011/05/04/2037057.html https://www.cnblogs.com/duanx ...
- 聊聊JVM(九)理解进入safepoint时如何让Java线程全部阻塞
在这篇聊聊JVM(六)理解JVM的safepoint 中说了safepoint的基本概念,VM thread在进行GC前,必须要让所有的Java线程阻塞,从而stop the world,开始标记.J ...
- 聊聊JVM(六)理解JVM的safepoint
safepoint是JVM里面很重要的一个概念,在很多场景下都会看到它,尤其是在GC的时候.这篇讲讲safepoint.本人不是做JVM实现研究的,很多地方只能点到为止,希望能够讲清楚这个概念,具体的 ...
- Presto日志中出现大量的Triggering GC to avoid Code Cache eviction bugs
问题描述: Presto日志中出现大量的 2017-07-31T15:31:21.505+0800 INFO Code-Cache-GC-Trigger com.facebook.presto.ser ...
- 聊聊JVM(八)说说GC标记阶段的一些事
这篇说说GC标记阶段的一些事情,尝试把一些概念说清楚.本人不是研究JVM实现的,如果表述有问题请查看参考资料进一步学习,推荐高级语言虚拟机圈子 ,里面有很多好的文章值得一看. GC最简单的理解就是先把 ...
- java eden space_JVM虚拟机20:内存区域详解(Eden Space、Survivor Space、Old Gen、Code Cache和Perm Gen)...
1.内存区域划分 根据我们之前介绍的垃圾收集算法,限定商用虚拟机基本都采用分代收集算法进行垃圾回收.根据对象的生命周期的不同将内存划分为几块,然后根据各块的特点采用最适当的收集算法.大批对象死去.少量 ...
- java eden space_JVM内存区域详解(Eden Space、Survivor Space、Old Gen、Code Cache和Perm Gen)...
JVM区域总体分两类,heap区和非heap区. heap区又分为: Eden Space(伊甸园). Survivor Space(幸存者区). Old Gen(老年代). 非heap区又分: Co ...
- java old区域_JVM内存区域详解(Eden Space、Survivor Space、Old Gen、Code Cache和Perm Gen)...
JVM区域总体分两类,heap区和非heap区. heap区又分为: Eden Space(伊甸园). Survivor Space(幸存者区). Old Gen(老年代). 非heap区又分: Co ...
- 聊聊jvm的CompressedClassSpace
序 本文主要研究一下jvm的CompressedClassSpace CompressedClassSpace java8移除了permanent generation,然后class metadat ...
最新文章
- 乐山计算机学校3十3,学校传真
- 天啦噜!生产机器连接数飙升到上万,背后发生了什么?
- 愚蠢的CNN,换个马甲就认不出猫!但,这病能治 | ICLR Oral
- 简易嵌入式管理平台 C 实现
- vs2015 全局头文件 库文件引用设置方法
- 零基础实战迁移学习VGG16解决图像分类问题
- HDU1576 A/B 费马小定理
- f12控制台如何查看consul_如何打印consul的错误信息
- 一位非常要好的朋友,零基础转行 Python!
- JavaScript call,apply和prototype的介绍,区别
- 大数据预测实战-随机森林预测实战(三)-数据与特征对模型的影响
- NRF24L01 + STC15F204EA 无线通信 源代码
- 用Redis实现分布式锁 与 实现任务队列
- java 反序列化 怎么知道类_理解java中的序列化与反序列化
- python实现文本翻译
- 文件二维码:在线直接扫一扫二维码查看下载资料
- java poi 合并单元格 边框显示不全
- 今日接手一个项目,服务器重启后,mysql启动失败
- C学习笔记——(4)数组和字符串说明,以及冒泡排序法
- 【游戏编程扯淡精粹】游戏编程设计模式
热门文章
- Python实战 | 爬取当当网 TOP500 畅销书
- 我用Python写了一个PDF转换器!
- 关于Android多线程编译
- python编写会计凭证金蝶_如何在金蝶财务软件中录入会计凭证
- C-------------使用scanf输入字符串的故事;
- 程控交换原理教学,程控数字交换系统实验设备
- shopex php5.3 无法安装,php版本导致shopex4.8.5安装的问题_PHP教程
- 通用WsSocket压力测试工具
- 单片机基础知识之定时计数器和寄存器
- 技术干货:赛车游戏中最短路径和最小曲率路径算法