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