java - 为什么 JIT 会在启动时编译一些方法?

标签 java optimization jvm jit

我正在研究一个非常简单的代码块上的 JIT 行为:

public class PlayWithAssembly {

    public static void main(String[] args) {
        Random random = new Random();
        random.nextInt();
    }
}

实际上,就我的问题而言,main 方法的内容完全无关紧要。我在 Ubuntu 16.04.5 上使用 OpenJDK 10.0.1 并使用以下命令运行以下代码 java -Xbatch -XX:+PrintCompilation -XX:CompileThreshold=1000000 -cp 目标/类 com.xxx.playground.internal.bytecode.PlayWithAssembly

由于 CompileThreshold 设置为一个非常高的值,我不希望 JIT 编译任何东西,我宁愿希望 JVM 在实践中完全以解释模式运行这个例子。但是当运行上面的命令时,我得到了以下已编译方法的列表(它们都是 JDK 的一部分):

 47    1    b  3       java.lang.StringLatin1::hashCode (42 bytes)
 50    2    b  3       java.util.concurrent.ConcurrentHashMap::tabAt (22 bytes)
 51    3     n 0       jdk.internal.misc.Unsafe::getObjectVolatile (native)   
 55    4    b  3       java.lang.Object::<init> (1 bytes)
 56    5    b  3       java.lang.String::isLatin1 (19 bytes)
 56    6    b  3       java.lang.String::hashCode (49 bytes)
 57    7    b  3       java.lang.String::coder (15 bytes)
 58    8    b  3       java.lang.Math::floorMod (10 bytes)
 59    9    b  3       java.util.ImmutableCollections$SetN::probe (60 bytes)
 62   10    b  1       java.util.ImmutableCollections$Set0::hashCode (2 bytes)
 62   11    b  3       java.lang.String::equals (65 bytes)
 64   12    b  1       java.util.Collections$EmptySet::hashCode (2 bytes)
 65   13    b  3       java.lang.StringLatin1::equals (36 bytes)
 66   14    b  3       java.util.Collections::emptySet (4 bytes)
 66   15    b  3       java.lang.module.ModuleDescriptor$Exports::<init> (10 bytes)
 67   16    b  4       java.lang.StringLatin1::hashCode (42 bytes)
 71    1       3       java.lang.StringLatin1::hashCode (42 bytes)   made not entrant
 72   17    b  3       java.lang.module.ModuleDescriptor$Exports::hashCode (38 bytes)
 73   18    b  3       java.util.Objects::equals (23 bytes)
 73   19    b  3       java.util.Objects::requireNonNull (14 bytes)
 74   20    b  3       java.util.AbstractCollection::<init> (5 bytes)
 76   21    b  3       java.util.AbstractSet::<init> (5 bytes)
 76   22    b  3       java.util.ImmutableCollections$AbstractImmutableSet::<init> (5 bytes)
 77   23    b  1       java.lang.Object::<init> (1 bytes)
 77    4       3       java.lang.Object::<init> (1 bytes)   made not entrant
 81   24    b  1       java.lang.module.ModuleDescriptor::name (5 bytes)
 82   25    b  1       java.lang.module.ModuleReference::descriptor (5 bytes)
 88   26    b  3       java.lang.String::charAt (25 bytes)
 93   27    b  3       java.util.concurrent.ConcurrentHashMap::spread (10 bytes)
 94   28    b  3       java.util.ImmutableCollections$SetN$1::hasNext (47 bytes)
 95   29    b  3       java.util.ImmutableCollections$SetN$1::next (35 bytes)
 96   30    b  3       java.util.Set::of (66 bytes)
 98   31    b  1       java.util.KeyValueHolder::getKey (5 bytes)
 99   32    b  1       java.util.KeyValueHolder::getValue (5 bytes)
100   33    b  3       java.util.ImmutableCollections$MapN::probe (64 bytes)
101   34    b  3       java.util.KeyValueHolder::<init> (21 bytes)
102   35    b  3       java.util.ImmutableCollections$MapN::get (21 bytes)
103   36     n 0       java.lang.Object::hashCode (native)   
103   37    b  3       jdk.internal.module.ModuleReferenceImpl::hashCode (56 bytes)
105   38    b  3       java.util.HashMap::hash (20 bytes)
106   39   !b  3       java.util.concurrent.ConcurrentHashMap::putVal (432 bytes)
112   40     n 0       jdk.internal.misc.Unsafe::compareAndSetLong (native)   
112   41    b  3       java.util.concurrent.ConcurrentHashMap::putIfAbsent (8 bytes)
112   42    b  1       java.lang.module.ResolvedModule::reference (5 bytes)
113   43    b  3       java.util.concurrent.ConcurrentHashMap::addCount (289 bytes)
115    2       3       java.util.concurrent.ConcurrentHashMap::tabAt (22 bytes)   made not entrant
115   39   !   3       java.util.concurrent.ConcurrentHashMap::putVal (432 bytes)   made not entrant
115   44    b  3       jdk.internal.misc.Unsafe::getObjectAcquire (7 bytes)
116   45    b  3       java.util.concurrent.ConcurrentHashMap::tabAt (22 bytes)
116   46     n 0       jdk.internal.misc.Unsafe::compareAndSetObject (native)   
117   47    b  3       java.util.concurrent.ConcurrentHashMap$Node::<init> (20 bytes)
117   48   !b  3       java.util.concurrent.ConcurrentHashMap::putVal (432 bytes)
120   49    b  3       java.util.concurrent.ConcurrentHashMap::casTabAt (21 bytes)
122   50    b  3       java.util.HashMap::getNode (148 bytes)
124   51    b  3       java.lang.String::length (11 bytes)
125   52    b  3       java.lang.StringLatin1::canEncode (13 bytes)
126   53    b  3       java.util.HashMap::put (13 bytes)
127   54     n 0       java.lang.System::arraycopy (native)   (static)
128   55    b  3       java.util.HashMap$Node::<init> (26 bytes)
128   56    b  3       java.util.HashMap::newNode (13 bytes)
129   57    b  3       java.util.HashMap::afterNodeInsertion (1 bytes)
129   58    b  3       java.util.Optional::ofNullable (15 bytes)
131   59    b  3       java.util.HashMap::get (23 bytes)
132   60    b  3       java.util.HashMap::putVal (300 bytes)
135   61    b  1       java.lang.module.ModuleDescriptor$Exports::source (5 bytes)
135   62    b  1       java.util.Collections$1::hasNext (5 bytes)
136   63    b  3       java.lang.module.ResolvedModule::name (11 bytes)
137   64    b  3       java.util.HashSet::add (20 bytes)
137   65    b  1       java.util.Collections$EmptySet::isEmpty (2 bytes)
138   66    b  3       java.lang.module.ResolvedModule::hashCode (16 bytes)
139   67    b  3       java.lang.module.ModuleDescriptor$Exports::isQualified (18 bytes)
140   68    b  1       java.lang.module.ModuleDescriptor::isAutomatic (5 bytes)
140   69    b  3       java.util.AbstractMap::<init> (5 bytes)
141   70    b  1       java.lang.module.ModuleDescriptor$Exports::targets (5 bytes)
141   71    b  1       java.lang.module.ResolvedModule::configuration (5 bytes)
142   72    b  3       java.util.HashMap::<init> (11 bytes)
142   73    b  3       java.util.ImmutableCollections$Set2$1::hasNext (14 bytes)
143   74    b  4       java.util.ImmutableCollections$SetN$1::hasNext (47 bytes)
148   28       3       java.util.ImmutableCollections$SetN$1::hasNext (47 bytes)   made not entrant
149   75    b  1       java.util.ImmutableCollections$Set1::size (2 bytes)
150   76    b  3       java.lang.Math::min (11 bytes)
152   77    b  3       java.util.AbstractCollection::isEmpty (13 bytes)
153   78    b  4       java.lang.String::hashCode (49 bytes)
160    6       3       java.lang.String::hashCode (49 bytes)   made not entrant
162   79    b  3       java.util.Map::entry (10 bytes)
165   80    b  1       java.lang.module.ModuleDescriptor::isOpen (5 bytes)
167   81    b  1       java.util.HashMap::afterNodeInsertion (1 bytes)
167   57       3       java.util.HashMap::afterNodeInsertion (1 bytes)   made not entrant
168   82    b  3       jdk.internal.module.ModuleBootstrap$2::hasNext (30 bytes)
169   83    b  3       java.util.HashMap::resize (356 bytes)
171   84    b  3       java.util.Collections$UnmodifiableCollection$1::hasNext (10 bytes)
172   85    b  3       jdk.internal.module.ModuleBootstrap$2::next (52 bytes)
173   86    b  3       java.util.HashMap::putIfAbsent (13 bytes)
174   87     n 0       java.lang.Module::addExportsToAllUnnamed0 (native)   (static)
175   88    b  1       java.lang.Module::getDescriptor (5 bytes)
182   78       4       java.lang.String::hashCode (49 bytes)   made not entrant
185   89    b  3       java.lang.StringLatin1::indexOf (61 bytes)
187   23       1       java.lang.Object::<init> (1 bytes)   made not entrant
195   90    b  1       java.lang.Object::<init> (1 bytes)
197   91    b  3       java.lang.String::hashCode (49 bytes) 

我试图将这些方法与内在函数列表匹配,但它不匹配,所以我的问题是:为什么这些方法被编译(而其他方法没有),我是否可以控制它?

最佳答案

来自 the documentation of -XX:CompileThreshold :

This option is ignored when tiered compilation is enabled;
see the option -XX:-TieredCompilation.

因此,当指定 -XX:-TieredCompilation 时,这些条目中的大部分将消失,但是,一些条目可能仍然不受基于计数器的编译决策的影响。

关于java - 为什么 JIT 会在启动时编译一些方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53418271/

相关文章:

garbage-collection - 我怎么知道谁在 spark streaming 程序中调用了 System.gc()?

java - java中的相对文件路径

java - 延迟访问服务器以尽量避开高峰时间

java - 运行 Java,无需进行数组边界检查、强制转换检查等

mysql - 优化嵌套查询

java - 我真的需要定义 Java 最小堆大小吗

java - JVM 在启动时锁定 JAR 文件

java - Spring Web Flow - 如何使用 conversationScope 中已有的值设置单元测试?

java - Mongo spring 查询两个字段相等的情况

java - 如何使用 Java API 在 Alfresco 中创建文档链接?