Talk about Code Cache of jvm

Posted by rjs34 on Sat, 11 May 2019 10:40:14 +0200

order

This paper mainly studies the Code Cache of jvm.

Code Cache

The memory space of native code generated by JVM is called Code Cache; JIT compilation, JNI and so on compile code to native code, and the native code generated by JIT occupies most of the space of Code Cache.

Related parameters

Codecache Size Options

  • -XX:InitialCodeCacheSize

Used to set the initial CodeCache size

  • -XX:ReservedCodeCacheSize

Used to set the maximum size of Reserved code cache, usually 240M by default

  • -XX:CodeCacheExpansionSize

The expansion size used to set the code cache is usually 64K by default

Codecache Flush Options

  • -XX:+UseCodeCacheFlushing

Whether to try to clean up the code cache when it is full, or close the compilation if it is not enough, the default is false

Compilation Policy Options

  • -XX:CompileThreshold

Method triggers the number of calls at compile time, default is 10000

  • -XX:OnStackReplacePercentage

The threshold value for OSR compilation triggered by the number of executions of the loop execution code in the method is 140 by default.

Compilation Limit Options

  • -XX:MaxInlineLevel

For maximum inline depth of nested calls, default is 9

  • -XX:MaxInlineSize

The maximum bytecode size that the method can be inlined, defaulting to 35

  • -XX:MinInliningThreshold

Method can be inlined with a minimum number of calls, defaulting to 250

  • -XX:+InlineSynchronizedMethods

Whether inline synchronized methods are allowed by default to true

Diagnostic Options

  • - XX:+PrintFlagsFinal (not enabled by default)

Used to view all settable parameters and final values (JDK 6 update 21 is available only at the beginning), the default does not include diagnostic or experimental systems. If you want to see the information of these two parameters in the output of - XX:+PrintFlagsFinal, you need to explicitly specify - XX:+Unlock Diagnostic VMOptions/ XX:+Unlock Experimental VMOptions (-XX:+PrintCommandLineFlags) to show all parameters different from the original default values and their values after VM initialization.

  • - XX:+PrintCodeCache (not enabled by default)

- XX:+PrintCodeCache for output code cache usage when jvm closes

  • - XX:+PrintCodeCacheOnCompilation (not enabled by default)

Used to output code cache usage at each time the method is compiled

View Code Cache usage

-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
  • The jvm startup parameter plus - XX:+PrintCodeCache can output the usage of code cache when the jvm is closed
  • There are three parts to show: non-profiled nmethods, profiled nmethods and non-nmethods.
  • Among them, size is the maximum limit size, use is the actual usage, max_use is the high water mark of use size, free is derived from size-use.

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

Compiler. code cache using jcmd can also view the use of code cache, the output is the same as - 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)

VM.native_memory using jcmd can also view the use of code cache (Code section), which is Memory tracking used by the compiler when generating code

View using 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 contains HEAP and NON_HEAP, where code cache belongs to NON_HEAP, and its output is as follows:

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 application view

/ # 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 uses micrometer to provide index query through the / actuator/metrics interface, where code cache is in jvm.memory.used metric It is based on MemoryPoolMXBean, as detailed in micrometer-core-1.1.3-sources.jar!/io/micrometer/core/instrument/binder/jvm/JvmMemoryMetrics.java

Summary

  • The memory space of native code generated by JVM is called Code Cache; JIT compilation, JNI and so on compile code to native code, and the native code generated by JIT occupies most of the space of Code Cache.
  • - XX: Reserved code cache Size is used to set the maximum size of Reserved code cache, which is usually defaulted to 240M; for some applications, 240M may be too large, and the code cache may not be filled in, which is equivalent to unconstrained, so JIT will continue to compile any code it thinks it can compile.
  • There are several ways to view the memory usage of Code Cache:
    • The jvm startup parameter plus - XX:+PrintCodeCache can output the usage of code cache when the jvm is closed
    • Using jcmd's Compiler.codecache, the output is the same as - XX:+PrintCodeCache.
    • VM.native_memory using jcmd can also view the use of code cache (Code section)
    • Using JMX to get MemoryPoolMXBean whose name is CodeHeap in the NON_HEAP type gives you code cache usage
    • If it is a spring boot application, it uses micrometer to provide index query function through the / actuator/metrics interface, where code cache is in jvm. memory. user metric

doc

Topics: Programming jvm Spring Java curl