Java 对于相同的方法,JVM如何决定使用哪个nmethod

Java 对于相同的方法,JVM如何决定使用哪个nmethod,java,jvm,jit,Java,Jvm,Jit,据我所知,JIT编译的机器代码存储在nmethod中。当osr发生时,整个方法也将被编译,而不仅仅是循环部分。因此,同一个方法可能有几个nmethod(osr或方法编译) 我运行一个tomcat应用程序并打开JVM标志-XX:+PrintTiereEvents。查找方法“org.apache.coyote.AbstractProcessor.parseHost”总是经过编译,其运行级别为0(解释器执行),就好像没有使用nmethod一样 399.895003: [loop level=0 [or

据我所知,JIT编译的机器代码存储在nmethod中。当osr发生时,整个方法也将被编译,而不仅仅是循环部分。因此,同一个方法可能有几个nmethod(osr或方法编译)

我运行一个tomcat应用程序并打开JVM标志-XX:+PrintTiereEvents。查找方法“org.apache.coyote.AbstractProcessor.parseHost”总是经过编译,其运行级别为0(解释器执行),就好像没有使用nmethod一样

399.895003: [loop level=0 [org.apache.coyote.AbstractProcessor.parseHost(Lorg/apache/tomcat/util/buf/MessageBytes;)V] @190 queues=0,0 rate=0.946396 k=1.00,1.00 total=1684,79876 mdo=1538(0),77824(0) max levels=4,4 compilable=c1,c1-osr,c2,c2-osr status=idle]
399.895053: [compile level=4 [org.apache.coyote.AbstractProcessor.parseHost(Lorg/apache/tomcat/util/buf/MessageBytes;)V] @190 queues=0,0 rate=0.946396 k=1.00,1.00]

401.924422: [loop level=0 [org.apache.coyote.AbstractProcessor.parseHost(Lorg/apache/tomcat/util/buf/MessageBytes;)V] @190 queues=0,0 rate=1.021956 k=1.00,1.00 total=1684,81924 mdo=1538(0),79872(0) max levels=4,4 compilable=c1,c1-osr,c2,c2-osr status=idle]
401.924488: [compile level=4 [org.apache.coyote.AbstractProcessor.parseHost(Lorg/apache/tomcat/util/buf/MessageBytes;)V] @190 queues=0,0 rate=1.021956 k=1.00,1.00]

402.915345: [loop level=0 [org.apache.coyote.AbstractProcessor.parseHost(Lorg/apache/tomcat/util/buf/MessageBytes;)V] @190 queues=0,0 rate=0.996109 k=1.00,1.00 total=1684,82948 mdo=1538(0),80896(0) max levels=4,4 compilable=c1,c1-osr,c2,c2-osr status=idle]
402.915398: [compile level=4 [org.apache.coyote.AbstractProcessor.parseHost(Lorg/apache/tomcat/util/buf/MessageBytes;)V] @190 queues=0,0 rate=0.996109 k=1.00,1.00]
我转储该方法的nmethods

address:0x00007f43cb17ce50 || size:2400 || methodName:NMethod for org/apache/coyote/AbstractProcessor.parseHost(Lorg/apache/tomcat/util/buf/MessageBytes;)V || isOSR:true || lockedByVm:false || _entry_bci:190|| _state:0|| _exception_offset:1680|| _deoptimize_offset:1685|| _deoptimize_mh_offset:-1|| _orig_pc_offset:64|| _stub_offset:1680|| _consts_offset:368|| _oops_offset:1704|| _metadata_offset:1712|| _scopes_data_offset:1760|| _scopes_pcs_offset:2152|| _dependencies_offset:2344|| _handler_table_offset:2352|| _nul_chk_table_offset:2352|| _nmethod_end_offset:2400|| _stack_traversal_mark:0|| _compile_id:19658|| _comp_level:4|| _marked_for_deoptimization:0|| _entry_point:0x00007f43cb17cfc0|| _verified_entry_point:0x00007f43cb17cfc0|| _osr_entry_point:0x00007f43cb17cfd0

address:0x00007f43cb1813d0 || size:10152 || methodName:NMethod for org/apache/coyote/AbstractProcessor.parseHost(Lorg/apache/tomcat/util/buf/MessageBytes;)V || isOSR:false || lockedByVm:false || _entry_bci:-1|| _state:0|| _exception_offset:6235|| _deoptimize_offset:6240|| _deoptimize_mh_offset:-1|| _orig_pc_offset:64|| _stub_offset:6160|| _consts_offset:592|| _oops_offset:6256|| _metadata_offset:6296|| _scopes_data_offset:6520|| _scopes_pcs_offset:9040|| _dependencies_offset:9808|| _handler_table_offset:9848|| _nul_chk_table_offset:10040|| _nmethod_end_offset:10152|| _stack_traversal_mark:0|| _compile_id:25500|| _comp_level:4|| _marked_for_deoptimization:0|| _entry_point:0x00007f43cb181620|| _verified_entry_point:0x00007f43cb181640||_osr_entry_point:0x00007f43cb181620

address:0x00007f43cd81fc50 || size:20000 || methodName:NMethod for org/apache/coyote/AbstractProcessor.parseHost(Lorg/apache/tomcat/util/buf/MessageBytes;)V || isOSR:true || lockedByVm:false || _entry_bci:105|| _state:0|| _exception_offset:13508|| _deoptimize_offset:13632|| _deoptimize_mh_offset:-1|| _orig_pc_offset:328|| _stub_offset:13168|| _consts_offset:1104|| _oops_offset:13656|| _metadata_offset:13704|| _scopes_data_offset:13888|| _scopes_pcs_offset:17584|| _dependencies_offset:19168|| _handler_table_offset:19192|| _nul_chk_table_offset:19720|| _nmethod_end_offset:20000|| _stack_traversal_mark:0|| _compile_id:25194|| _comp_level:3|| _marked_for_deoptimization:0|| _entry_point:0x00007f43cd8200a0|| _verified_entry_point:0x00007f43cd8200c0|| _osr_entry_point:0x00007f43cd82287b
每个nmethod都有-字节码索引,该nmethod可以在该索引处开始执行。非OSR编译具有
\u entry\u bci==InvocationEntryBci(-1)

为堆栈上替换(OSR)编译的方法永远不会用于常规方法项

事实上,一个Java方法最多只能有一个实际值(不包括OSR和AOT条目)。如果在更高的层次上重新编译了一个方法,则会替换条目以指向新代码,并且以前的nmethod会标记为
not_entrant
,尽管当前活动帧可能会继续运行旧版本。

每个nmethod都有一个字节码索引,该nmethod可以在该索引处开始执行。非OSR编译具有
\u entry\u bci==InvocationEntryBci(-1)

为堆栈上替换(OSR)编译的方法永远不会用于常规方法项

事实上,一个Java方法最多只能有一个实际值(不包括OSR和AOT条目)。如果在更高的层重新编译某个方法,则会替换该条目以指向新代码,并且以前的nmethods会标记为
not_entrant
,尽管当前活动帧可能会继续运行旧版本