Why JIT compiles some methods at the startup?
I'm looking into JIT behavior on a very simple block of code:
public class PlayWithAssembly {
public static void main(String args) {
Random random = new Random();
random.nextInt();
}
}
Actually, for the purpose of my question the content of the main
method is completely irrelevant. I'm running the following code using OpenJDK 10.0.1 on Ubuntu 16.04.5 and with the following command
java -Xbatch -XX:+PrintCompilation -XX:CompileThreshold=1000000 -cp target/classes com.xxx.playground.internal.bytecode.PlayWithAssembly
Since CompileThreshold
is set to a very high value I wouldn't expect JIT to compile anything, I would rather expect JVM to operate fully in interpreted mode in practice for this example. But when running the above command, I'm getting a following list of methods that have been compiled (all of them are part of 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)
I was trying to match these methods with the list of intrinsics but it does not match, so my questions are: why these methods are compiled (and others are not), and do I have any control over it?
java optimization jvm jit
add a comment |
I'm looking into JIT behavior on a very simple block of code:
public class PlayWithAssembly {
public static void main(String args) {
Random random = new Random();
random.nextInt();
}
}
Actually, for the purpose of my question the content of the main
method is completely irrelevant. I'm running the following code using OpenJDK 10.0.1 on Ubuntu 16.04.5 and with the following command
java -Xbatch -XX:+PrintCompilation -XX:CompileThreshold=1000000 -cp target/classes com.xxx.playground.internal.bytecode.PlayWithAssembly
Since CompileThreshold
is set to a very high value I wouldn't expect JIT to compile anything, I would rather expect JVM to operate fully in interpreted mode in practice for this example. But when running the above command, I'm getting a following list of methods that have been compiled (all of them are part of 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)
I was trying to match these methods with the list of intrinsics but it does not match, so my questions are: why these methods are compiled (and others are not), and do I have any control over it?
java optimization jvm jit
The JVM does a lot of processing as a part of starting up and these methods were called over 10,000 times (or looped 10,000) times. There is little benefit in triggering a method to compile the first time it is used (or before hand)
– Peter Lawrey
Nov 21 '18 at 19:00
@PeterLawrey yes, I'm fully aware of the trade off related to compiling the method right away. I tested it withCompileThreshold
set to1
and the code runs for over 4 seconds (with background compilation enabled). Do you have any starting point for digging the topic of what is JVM doing to run mymain
method?
– MateuszPrzybyla
Nov 21 '18 at 19:07
I would look at theLauncher
class. github.com/frohoff/jdk8u-jdk/blob/master/src/share/classes/sun/…
– Peter Lawrey
Nov 22 '18 at 10:33
add a comment |
I'm looking into JIT behavior on a very simple block of code:
public class PlayWithAssembly {
public static void main(String args) {
Random random = new Random();
random.nextInt();
}
}
Actually, for the purpose of my question the content of the main
method is completely irrelevant. I'm running the following code using OpenJDK 10.0.1 on Ubuntu 16.04.5 and with the following command
java -Xbatch -XX:+PrintCompilation -XX:CompileThreshold=1000000 -cp target/classes com.xxx.playground.internal.bytecode.PlayWithAssembly
Since CompileThreshold
is set to a very high value I wouldn't expect JIT to compile anything, I would rather expect JVM to operate fully in interpreted mode in practice for this example. But when running the above command, I'm getting a following list of methods that have been compiled (all of them are part of 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)
I was trying to match these methods with the list of intrinsics but it does not match, so my questions are: why these methods are compiled (and others are not), and do I have any control over it?
java optimization jvm jit
I'm looking into JIT behavior on a very simple block of code:
public class PlayWithAssembly {
public static void main(String args) {
Random random = new Random();
random.nextInt();
}
}
Actually, for the purpose of my question the content of the main
method is completely irrelevant. I'm running the following code using OpenJDK 10.0.1 on Ubuntu 16.04.5 and with the following command
java -Xbatch -XX:+PrintCompilation -XX:CompileThreshold=1000000 -cp target/classes com.xxx.playground.internal.bytecode.PlayWithAssembly
Since CompileThreshold
is set to a very high value I wouldn't expect JIT to compile anything, I would rather expect JVM to operate fully in interpreted mode in practice for this example. But when running the above command, I'm getting a following list of methods that have been compiled (all of them are part of 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)
I was trying to match these methods with the list of intrinsics but it does not match, so my questions are: why these methods are compiled (and others are not), and do I have any control over it?
java optimization jvm jit
java optimization jvm jit
asked Nov 21 '18 at 18:16
MateuszPrzybylaMateuszPrzybyla
609514
609514
The JVM does a lot of processing as a part of starting up and these methods were called over 10,000 times (or looped 10,000) times. There is little benefit in triggering a method to compile the first time it is used (or before hand)
– Peter Lawrey
Nov 21 '18 at 19:00
@PeterLawrey yes, I'm fully aware of the trade off related to compiling the method right away. I tested it withCompileThreshold
set to1
and the code runs for over 4 seconds (with background compilation enabled). Do you have any starting point for digging the topic of what is JVM doing to run mymain
method?
– MateuszPrzybyla
Nov 21 '18 at 19:07
I would look at theLauncher
class. github.com/frohoff/jdk8u-jdk/blob/master/src/share/classes/sun/…
– Peter Lawrey
Nov 22 '18 at 10:33
add a comment |
The JVM does a lot of processing as a part of starting up and these methods were called over 10,000 times (or looped 10,000) times. There is little benefit in triggering a method to compile the first time it is used (or before hand)
– Peter Lawrey
Nov 21 '18 at 19:00
@PeterLawrey yes, I'm fully aware of the trade off related to compiling the method right away. I tested it withCompileThreshold
set to1
and the code runs for over 4 seconds (with background compilation enabled). Do you have any starting point for digging the topic of what is JVM doing to run mymain
method?
– MateuszPrzybyla
Nov 21 '18 at 19:07
I would look at theLauncher
class. github.com/frohoff/jdk8u-jdk/blob/master/src/share/classes/sun/…
– Peter Lawrey
Nov 22 '18 at 10:33
The JVM does a lot of processing as a part of starting up and these methods were called over 10,000 times (or looped 10,000) times. There is little benefit in triggering a method to compile the first time it is used (or before hand)
– Peter Lawrey
Nov 21 '18 at 19:00
The JVM does a lot of processing as a part of starting up and these methods were called over 10,000 times (or looped 10,000) times. There is little benefit in triggering a method to compile the first time it is used (or before hand)
– Peter Lawrey
Nov 21 '18 at 19:00
@PeterLawrey yes, I'm fully aware of the trade off related to compiling the method right away. I tested it with
CompileThreshold
set to 1
and the code runs for over 4 seconds (with background compilation enabled). Do you have any starting point for digging the topic of what is JVM doing to run my main
method?– MateuszPrzybyla
Nov 21 '18 at 19:07
@PeterLawrey yes, I'm fully aware of the trade off related to compiling the method right away. I tested it with
CompileThreshold
set to 1
and the code runs for over 4 seconds (with background compilation enabled). Do you have any starting point for digging the topic of what is JVM doing to run my main
method?– MateuszPrzybyla
Nov 21 '18 at 19:07
I would look at the
Launcher
class. github.com/frohoff/jdk8u-jdk/blob/master/src/share/classes/sun/…– Peter Lawrey
Nov 22 '18 at 10:33
I would look at the
Launcher
class. github.com/frohoff/jdk8u-jdk/blob/master/src/share/classes/sun/…– Peter Lawrey
Nov 22 '18 at 10:33
add a comment |
1 Answer
1
active
oldest
votes
From the documentation of -XX:CompileThreshold
:
This option is ignored when tiered compilation is enabled;
see the option-XX:-TieredCompilation
.
So when specifying -XX:-TieredCompilation
, most of these entries will go away, however, some entries may still be exempted from the counter based compilation decision.
1
Note: there is nothing special from a JIT point of view about the code called and compiled beforemain()
is called. IThey are compiled for the same reasons code after main() is called is compiled +1
– Peter Lawrey
Nov 21 '18 at 19:01
That's it! I added-XX:-TieredCompilation
and now I feel that I really control the threshold. What now grabbed my attention is that even after settingCompileThreshold
to40000
the methodjava.lang.StringLatin1::hashCode
still compiles! That means a lot of stuff going on around computing hash codes for Strings happening even before runningmain()
method! Actually for my environment that was exactly45955
invocations.
– MateuszPrzybyla
Nov 21 '18 at 19:03
More about compilation policy: stackoverflow.com/a/35614237/3448419
– apangin
Nov 21 '18 at 19:09
@MateuszPrzybyla well, hashing strings happens all the times. Think system properties (not only those present, each queried key needs to be hashed too), all loaded classes, locale data, file system cache, etc. I don’t know, perhaps, even the string interning resorts to the Java side hash code implementation. Unlikely to happen at startup, but even the garbage collector may hash strings when de-duplication is activated…
– Holger
Nov 22 '18 at 8:15
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53418271%2fwhy-jit-compiles-some-methods-at-the-startup%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
From the documentation of -XX:CompileThreshold
:
This option is ignored when tiered compilation is enabled;
see the option-XX:-TieredCompilation
.
So when specifying -XX:-TieredCompilation
, most of these entries will go away, however, some entries may still be exempted from the counter based compilation decision.
1
Note: there is nothing special from a JIT point of view about the code called and compiled beforemain()
is called. IThey are compiled for the same reasons code after main() is called is compiled +1
– Peter Lawrey
Nov 21 '18 at 19:01
That's it! I added-XX:-TieredCompilation
and now I feel that I really control the threshold. What now grabbed my attention is that even after settingCompileThreshold
to40000
the methodjava.lang.StringLatin1::hashCode
still compiles! That means a lot of stuff going on around computing hash codes for Strings happening even before runningmain()
method! Actually for my environment that was exactly45955
invocations.
– MateuszPrzybyla
Nov 21 '18 at 19:03
More about compilation policy: stackoverflow.com/a/35614237/3448419
– apangin
Nov 21 '18 at 19:09
@MateuszPrzybyla well, hashing strings happens all the times. Think system properties (not only those present, each queried key needs to be hashed too), all loaded classes, locale data, file system cache, etc. I don’t know, perhaps, even the string interning resorts to the Java side hash code implementation. Unlikely to happen at startup, but even the garbage collector may hash strings when de-duplication is activated…
– Holger
Nov 22 '18 at 8:15
add a comment |
From the documentation of -XX:CompileThreshold
:
This option is ignored when tiered compilation is enabled;
see the option-XX:-TieredCompilation
.
So when specifying -XX:-TieredCompilation
, most of these entries will go away, however, some entries may still be exempted from the counter based compilation decision.
1
Note: there is nothing special from a JIT point of view about the code called and compiled beforemain()
is called. IThey are compiled for the same reasons code after main() is called is compiled +1
– Peter Lawrey
Nov 21 '18 at 19:01
That's it! I added-XX:-TieredCompilation
and now I feel that I really control the threshold. What now grabbed my attention is that even after settingCompileThreshold
to40000
the methodjava.lang.StringLatin1::hashCode
still compiles! That means a lot of stuff going on around computing hash codes for Strings happening even before runningmain()
method! Actually for my environment that was exactly45955
invocations.
– MateuszPrzybyla
Nov 21 '18 at 19:03
More about compilation policy: stackoverflow.com/a/35614237/3448419
– apangin
Nov 21 '18 at 19:09
@MateuszPrzybyla well, hashing strings happens all the times. Think system properties (not only those present, each queried key needs to be hashed too), all loaded classes, locale data, file system cache, etc. I don’t know, perhaps, even the string interning resorts to the Java side hash code implementation. Unlikely to happen at startup, but even the garbage collector may hash strings when de-duplication is activated…
– Holger
Nov 22 '18 at 8:15
add a comment |
From the documentation of -XX:CompileThreshold
:
This option is ignored when tiered compilation is enabled;
see the option-XX:-TieredCompilation
.
So when specifying -XX:-TieredCompilation
, most of these entries will go away, however, some entries may still be exempted from the counter based compilation decision.
From the documentation of -XX:CompileThreshold
:
This option is ignored when tiered compilation is enabled;
see the option-XX:-TieredCompilation
.
So when specifying -XX:-TieredCompilation
, most of these entries will go away, however, some entries may still be exempted from the counter based compilation decision.
answered Nov 21 '18 at 18:30
HolgerHolger
163k23231438
163k23231438
1
Note: there is nothing special from a JIT point of view about the code called and compiled beforemain()
is called. IThey are compiled for the same reasons code after main() is called is compiled +1
– Peter Lawrey
Nov 21 '18 at 19:01
That's it! I added-XX:-TieredCompilation
and now I feel that I really control the threshold. What now grabbed my attention is that even after settingCompileThreshold
to40000
the methodjava.lang.StringLatin1::hashCode
still compiles! That means a lot of stuff going on around computing hash codes for Strings happening even before runningmain()
method! Actually for my environment that was exactly45955
invocations.
– MateuszPrzybyla
Nov 21 '18 at 19:03
More about compilation policy: stackoverflow.com/a/35614237/3448419
– apangin
Nov 21 '18 at 19:09
@MateuszPrzybyla well, hashing strings happens all the times. Think system properties (not only those present, each queried key needs to be hashed too), all loaded classes, locale data, file system cache, etc. I don’t know, perhaps, even the string interning resorts to the Java side hash code implementation. Unlikely to happen at startup, but even the garbage collector may hash strings when de-duplication is activated…
– Holger
Nov 22 '18 at 8:15
add a comment |
1
Note: there is nothing special from a JIT point of view about the code called and compiled beforemain()
is called. IThey are compiled for the same reasons code after main() is called is compiled +1
– Peter Lawrey
Nov 21 '18 at 19:01
That's it! I added-XX:-TieredCompilation
and now I feel that I really control the threshold. What now grabbed my attention is that even after settingCompileThreshold
to40000
the methodjava.lang.StringLatin1::hashCode
still compiles! That means a lot of stuff going on around computing hash codes for Strings happening even before runningmain()
method! Actually for my environment that was exactly45955
invocations.
– MateuszPrzybyla
Nov 21 '18 at 19:03
More about compilation policy: stackoverflow.com/a/35614237/3448419
– apangin
Nov 21 '18 at 19:09
@MateuszPrzybyla well, hashing strings happens all the times. Think system properties (not only those present, each queried key needs to be hashed too), all loaded classes, locale data, file system cache, etc. I don’t know, perhaps, even the string interning resorts to the Java side hash code implementation. Unlikely to happen at startup, but even the garbage collector may hash strings when de-duplication is activated…
– Holger
Nov 22 '18 at 8:15
1
1
Note: there is nothing special from a JIT point of view about the code called and compiled before
main()
is called. IThey are compiled for the same reasons code after main() is called is compiled +1– Peter Lawrey
Nov 21 '18 at 19:01
Note: there is nothing special from a JIT point of view about the code called and compiled before
main()
is called. IThey are compiled for the same reasons code after main() is called is compiled +1– Peter Lawrey
Nov 21 '18 at 19:01
That's it! I added
-XX:-TieredCompilation
and now I feel that I really control the threshold. What now grabbed my attention is that even after setting CompileThreshold
to 40000
the method java.lang.StringLatin1::hashCode
still compiles! That means a lot of stuff going on around computing hash codes for Strings happening even before running main()
method! Actually for my environment that was exactly 45955
invocations.– MateuszPrzybyla
Nov 21 '18 at 19:03
That's it! I added
-XX:-TieredCompilation
and now I feel that I really control the threshold. What now grabbed my attention is that even after setting CompileThreshold
to 40000
the method java.lang.StringLatin1::hashCode
still compiles! That means a lot of stuff going on around computing hash codes for Strings happening even before running main()
method! Actually for my environment that was exactly 45955
invocations.– MateuszPrzybyla
Nov 21 '18 at 19:03
More about compilation policy: stackoverflow.com/a/35614237/3448419
– apangin
Nov 21 '18 at 19:09
More about compilation policy: stackoverflow.com/a/35614237/3448419
– apangin
Nov 21 '18 at 19:09
@MateuszPrzybyla well, hashing strings happens all the times. Think system properties (not only those present, each queried key needs to be hashed too), all loaded classes, locale data, file system cache, etc. I don’t know, perhaps, even the string interning resorts to the Java side hash code implementation. Unlikely to happen at startup, but even the garbage collector may hash strings when de-duplication is activated…
– Holger
Nov 22 '18 at 8:15
@MateuszPrzybyla well, hashing strings happens all the times. Think system properties (not only those present, each queried key needs to be hashed too), all loaded classes, locale data, file system cache, etc. I don’t know, perhaps, even the string interning resorts to the Java side hash code implementation. Unlikely to happen at startup, but even the garbage collector may hash strings when de-duplication is activated…
– Holger
Nov 22 '18 at 8:15
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53418271%2fwhy-jit-compiles-some-methods-at-the-startup%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
The JVM does a lot of processing as a part of starting up and these methods were called over 10,000 times (or looped 10,000) times. There is little benefit in triggering a method to compile the first time it is used (or before hand)
– Peter Lawrey
Nov 21 '18 at 19:00
@PeterLawrey yes, I'm fully aware of the trade off related to compiling the method right away. I tested it with
CompileThreshold
set to1
and the code runs for over 4 seconds (with background compilation enabled). Do you have any starting point for digging the topic of what is JVM doing to run mymain
method?– MateuszPrzybyla
Nov 21 '18 at 19:07
I would look at the
Launcher
class. github.com/frohoff/jdk8u-jdk/blob/master/src/share/classes/sun/…– Peter Lawrey
Nov 22 '18 at 10:33