hello, question about c1 and c2 compilers. if the server jvm is the default jvm that is being used, can c1 compilation still occur or is c2 the only compiler that is available? If it can occur is this any different than the c1 from client jvm? Im trying to hunt down a c2 compilerthread0 exception crash when its trying to inline methods and it's only occurring in production. If i exclude inline optimization from the compiler, the crash does not occur. Very recently I also noticed that the crash does not occur if the computer running the application has a pagefile virtual memory above 5000 mb +/-. the crash appears to me as an out of memory crash being manifested as something else but its hard to tell since the application crashes at seemingly random times. anywhere from 20 minutes to over several hours. when the application does crash, An event in windows event viewer is created a few minutes before warning about memory exhaustion and java is one of the programs being mentioned. Using jconsole there does not appear to be any memory leaks. I do have hs_err_pid & replay_pid logs available and the args used are -ea -Xmx512m -Xss2m -XX:CompileThreshold=1500
#Java 11 JIT HotSpot compiler inlining
1 messages · Page 1 of 1 (latest)
⌛ This post has been reserved for your question.
Hey @outer drum! Please use
/closeor theClose Postbutton above when you're finished. Please remember to follow the help guidelines. This post will be automatically closed after 300 minutes of inactivity.
TIP: Narrow down your issue to simple and precise questions to maximize the chance that others will reply in here.
Java uses tiered compilation by default for quite some time now
it first starts in interpreter mode and once some code is hot enough, it is JITed with C1
once it's executed even more often, it's further JITed with C2
for diagnosing the error, checkthe hs_err_pid file
it should tell you where the error occured
and make sure you're using the latest version of Java 11
and if you can,maybe also try with Java 17
I think I understand my confusion with c1 and c2 now. As for the crash, I know what method it’s trying to compile/inline when it crashes. I just don’t understand why the jvm would even crash in the first place when c2 is being used. I tried viewing the addresses that occurred in the stack but I don’t have symbols to get any information on the method that’s being executed. This does occur when using java 17 as well.
Can you show the contents of the hs err pid file?
If there is any sensitive data in it, make sure to redact that
@simple marten
the 3 native functions at the end of the stack frame are for creating threads iirc
Does your onGameTick method do anything special?
it could be related to https://bugs.openjdk.org/browse/JDK-8164318
it's a subscribed/listener method that handles the majority of the code within the project. Its a rather large method
it seems like the latest version of Java 11 from coretto is 11.0.20.9.1
you might want to try updating to that
or even better try with Java 17 or even 20 maybe
this one is java 17 incase you wanted to examine
Does the error also occur without the -XX:CompileThreshold=1500?
What is the KeeganToAPlugin#onGameTick method doing?
Is that method pretty long?
If the method is pretty big, try to split it in smaller methods
lots of array/list management, pathfinding, invoking methods to run on other subscribed/listened method. its a little over 2k lines
Normally, the JIT wouldn't even try to compile a single method like this
Are you sure it still crashes without the -XX:CompileThreshold=1500?
with or without this arg it still crashes. it takes longer without
the onGameTick is called about every .6 seconds
Is it really a single method that has almost 2k lines of code?
if so, you should split that into multiple methods
Yes
Try doing that so that you have no single method with more than ~100 lines of code
Is it trying to inline the method or could it be trying to inline the methods used inside of it?
then check whether it crashes again
it does some inlining but I don't think it does inlining with methods that big
I have another log somewhere where the crash does not originate from my own code, would you want to examine this one too?
the JIT works better with small methods
like if you have a few methods calling each other that are 2k lines together, it shouldn't be a problem
but with a single method that's that big, there are some difficulties
I think you might be pretty close to the limit where your method wouldn't be JITed at all
@simple marten logs provided from a mac user lead me here because the stack contained method names. I considered it a dead end since it was fixed in java 9. Are reoccurring bugs possible? I will try making methods smaller. May I ask what made you suspicious of large methods ?
the line
C2: 645710 23077 ! 4 net.storm.plugins.toa.KeeganToAPlugin::onGameTick (6758 bytes)
8000 bytes is when the JIT normally completely ignores a method
Do you know if I’m able to easily access symbols to view the jvm in something like IDA to search the addresses that show in the stack? Mac was able to produce the method names but not windows, but I do not know if it’s the same issue for windows
What do you mean with method names?
you could probably extract some things from the DLL
but I don't feel like that would help you much
In the log where it has jvm + address, on a mac machine it shows the method names after the address
with the DLL/SO file?
probably jvm.so
I would recommend you to still split up the method first
and check whether it still crashes
Okay I’ll try that. Thank you for taking the time to help 🙏
If you are finished with your post, please close it.
If you are not, please ignore this message.
Note that you will not be able to send further messages here after this post have been closed but you will be able to create new posts.
Alternatively, you could try to create a cpy of that project and remove stuff from the copy as long as you can reproduce the error
you can use git for making checkpoints so you can quickly go back to a point where you can reproduce it if you're familiar with git
@simple marten do you think its possible this issue could be an oom error that is manifesting as something else? as if the compiler is blowing up before it has a chance to crash with an oom error ? im not sure what it could mean if increasing virtual memory stops the crash, i feel like its related to memory usage. or like if the c2 is demanding to much memory when it begins ? I wont be able to test splitting the code into multiple methods until later, but i will get back to you on that
yes, it could be that something is out of memory
maybe even that the off-heap memory is insufficient
and even in that case, splitting up your methods into smaller method could help because that would cause the JIT to require less memory to process the method
okay thats good to know. wasn't sure if it was just a coincidence or not. you mentioned the compilethreshold, can this result in any issues with the compilers if its set to 1500? i noticed that the value is the same that the client jvm uses. maybe its too low to determine if something is "hot" or not
it changes how fast the JIT activates IIRC
I think a lower number means stuff is JITed faster/earlier
Also I think that client VM means C1 and server VM means C2
though by default, it should use both
thats what i was confused with earlier, server jvm is the only dll i can see that the application has a handle too
wasnt sure if the server jvm has its own client compiler inside of it or not
but your idea that it goes OOM when during JIT compilation could easily be the cause of your problem here
As I said previously, it should use tiered compilation by default
the C1 is also called the client JIT/client compiler whiole C2 is the server JIT/server compiler
by default, it first runs C1 once the code is sufficiently hot and then runs C2 at a later point in time once it gets even hotter
so if c1 and c2 have the same compilethreshold, could this be a problem? its hard to find such specific answers on this stuff
maybe though I don't really think so
again, ty for the help 🙏 i could pick your brain all day, but i'll stop here until the method splitting is tested

well just one more question lol, could large classes being used also be a factor in the crashing?
the entire class is 2600 lines
unlikely
but if you have classes that big, you should really consider refactoring them
321 to be exaact, appreciate the feedback/help ❤️
So you were able to split it up?
If so, does it still crash?
Not yet, just saw @outer drum's comments today it was never actually 2k. He doesn't have the actual source code so was probably just a guess on his end or something I mistakenly told him earlier on
Should be no big deal to slice it into smaller chunks I'll give it a shot
Basically this onGameTick is housing a whole boatload of other methods that it calls and that's grown to this size.. If you think it would make a difference I can group them together so the onGameTick just calls a function that calls 50 of them, and another function that calls 50 of them, etc
This is my understanding as well, client/server is just an older naming of C1/C2
Again though, thanks for the help I'll split things up and see how it goes before worrying about anything else
💤 Post marked as dormant
This post has been inactive for over 300 minutes, thus, it has been archived.
If your question was not answered yet, feel free to re-open this post or create a new one.
Only time will tell for certain, but it does seem like that may have done the trick, no one has crashed YET as far as I am aware since simply splitting up that method into a few different methods that it calls instead
if you are able to create a minimal reproducer without any libraries, you might be able to report it to OpenJDK