java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java jvm中Code Cache

Java jvm中Code Cache案例详解

作者:go4it

这篇文章主要介绍了Java jvm中Code Cache案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下

Code Cache

JVM生成的native code存放的内存空间称之为Code Cache;JIT编译、JNI等都会编译代码到native code,其中JIT生成的native code占用了Code Cache的绝大部分空间

相关参数

Codecache Size Options

用于设置初始CodeCache大小

用于设置Reserved code cache的最大大小,通常默认是240M

用于设置code cache的expansion size,通常默认是64K

Codecache Flush Options

是否在code cache满的时候先尝试清理一下,如果还是不够用再关闭编译,默认开启

Compilation Policy Options

方法触发编译时的调用次数,默认是10000

方法中循环执行部分代码的执行次数触发OSR编译时的阈值,默认是140

Compilation Limit Options

针对嵌套调用的最大内联深度,默认为9

方法可以被内联的最大bytecode大小,默认为35

方法可以被内联的最小调用次数,默认为250

是否允许内联synchronized methods,默认为true

Diagnostic Options

用于查看所有可设置的参数及最终值(JDK 6 update 21开始才可以用),默认是不包括diagnostic或experimental系的。如果要在-XX:+PrintFlagsFinal的输出里看到这两种参数的信息,分别需要显式指定-XX:+UnlockDiagnosticVMOptions / -XX:+UnlockExperimentalVMOptions(-XX:+PrintCommandLineFlags 这个参数的作用是显示出VM初始化完毕后所有跟最初的默认值不同的参数及它们的值)

-XX:+PrintCodeCache用于jvm关闭时输出code cache的使用情况

用于在方法每次被编译时输出code cache的使用情况

查看Code Cache的使用情况

-XX:+PrintCodeCache

CodeHeap 'non-profiled nmethods': size=120032Kb used=2154Kb max_used=2160Kb free=117877Kb
 bounds [0x00000001178ea000, 0x0000000117b5a000, 0x000000011ee22000]
CodeHeap 'profiled nmethods': size=120028Kb used=10849Kb max_used=11005Kb free=109178Kb
 bounds [0x00000001103b3000, 0x0000000110e73000, 0x00000001178ea000]
CodeHeap 'non-nmethods': size=5700Kb used=1177Kb max_used=1239Kb free=4522Kb
 bounds [0x000000010fe22000, 0x0000000110092000, 0x00000001103b3000]
 total_blobs=5638 nmethods=4183 adapters=435
 compilation: enabled
              stopped_count=0, restarted_count=0
 full_count=0

jcmd pid Compiler.codecache

/ # jcmd 1 Compiler.codecache
1:
CodeHeap 'non-profiled nmethods': size=120036Kb used=1582Kb max_used=1582Kb free=118453Kb
 bounds [0x00007f1e42226000, 0x00007f1e42496000, 0x00007f1e4975f000]
CodeHeap 'profiled nmethods': size=120032Kb used=9621Kb max_used=9621Kb free=110410Kb
 bounds [0x00007f1e3acee000, 0x00007f1e3b65e000, 0x00007f1e42226000]
CodeHeap 'non-nmethods': size=5692Kb used=1150Kb max_used=1198Kb free=4541Kb
 bounds [0x00007f1e3a75f000, 0x00007f1e3a9cf000, 0x00007f1e3acee000]
 total_blobs=5610 nmethods=4369 adapters=412
 compilation: enabled
              stopped_count=0, restarted_count=0
 full_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查看

    @Test
    public 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

小结

doc

15 Codecache Tuning

JVM的编译策略

What are ReservedCodeCacheSize and InitialCodeCacheSize?

Why does the JVM have a maximum inline depth?

Code Cache满导致应用性能降低

到此这篇关于Java jvm中Code Cache案例详解的文章就介绍到这了,更多相关Java jvm中Code Cache内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文