7

I'm new to Java. I was reading about JVM warmup and understand that it refers to the time it takes for the JVM to find the hotspots and JIT these sections of the code.

I also understood that I'll have to run my tests a few hundred times in order to do.

But the things I do not understand are as follows:

  1. How shall I determine the number of times a test should run before my JVM is fully warmed-up?

  2. Does this change JVM to JVM? I mean is it possible that if I'm able to warm-up my JVM by running 1000 iterations then someone else might end up needing more or less?

  3. Is running tests the only way to warm-up the JVM?

  4. When should I warm-up the JVM? I mean the frequency. Should I do it every-time I'm stopping and starting my application or just once after rebooting my servers?

This is my first question here. I read the guidelines before posting. Still if there are any mistakes please suggest the edits.

  • What kind of application are you talking about? Why do you think you need to warmup at all? Running tests will warmup the JVM that runs the test. Not the JVM that serves your application. – JB Nizet Apr 02 '16 at 07:33
  • Are you doing any type of benchmarking? – SMA Apr 02 '16 at 07:34
  • @SMA Yes, we are working on an algorithm to enrich a huge volume of trades received per second. –  Apr 02 '16 at 07:41
  • @JBNizet From what I read about JVM warm-up it seems that if I'm getting huge volume of trades then it will take less time if my JVM is already warmed-up. I'm still understand the concepts. How shall I warm-up the JVM that serves my application? –  Apr 02 '16 at 07:44
  • @MissMeme - You should never *warm up* your JVMs in production environments. Warming up is usually done to do proper benchmarking. – TheLostMind Apr 02 '16 at 07:46
  • 2
    You're most probably pre-optimizing. Just start your JVM, let it handle the first real requests and identify the hotspots: it will most probably be fast enough. If you're indeed receiving a huge number of requests, it will warm up quickly by itself. Most online apps are not CPU-bound anyway, but IO-bound. So if a method takes 0.5 millisecond more time when not warmed up, but spends 200 milliseconds in IO anyway, the difference will be negligible. – JB Nizet Apr 02 '16 at 07:48
  • @JBNizet Thanks for your valuable inputs. Could you please take some time out in answering the other queries as well and post the answer so that I can accept it? –  Apr 02 '16 at 07:54
  • @TheLostMind One of the links I encountered is this: https://dzone.com/articles/warming-your-jvm-superfast Is there any specific reasons that it should not be done in PROD? –  Apr 02 '16 at 07:56
  • @MissMeme when you reduce the CompileThreshold you are compiling/optimising based on less information. Sometimes this doesn't matter and waiting is not worth waiting, sometimes the code is optimised sub-optimally. In a complex applications it is very hard to find one right value for everything. You are better off starting with the defaults and warming up specific code if you find you have a problem with that code. – Peter Lawrey Apr 02 '16 at 11:10

3 Answers3

4

How shall I determine the number of times a test should run before my JVM is fully warmed-up?

Assuming you have the default -XX:CompileThreshold=10000 a method can be triggered to be compile after 10,000 calls or you have a loop in it which has iterated 10,000 times. This is queued for compilation in the background so it might take 12K - 20K iterations before you are running optimised code.

Note: the JIT can re-optimise code and you might see the timing change even after 10K or 1 million iterations.

Does this change JVM to JVM? I mean is it possible that if I'm able to warm-up my JVM by running 1000 iterations then someone else might end up needing more or less?

Yes. If you do more than you think you need this is the best way to cover more configurations.

Is running tests the only way to warm-up the JVM?

You should really run real code ideally. Running tests is better for reducing the impact of warming up the code so is more practical in production.

When should I warm-up the JVM? I mean the frequency. Should I do it every-time I'm stopping and starting my application or just once after rebooting my servers?

Whenever you start you JVM, you start from scratch. Even if the same JVM is already running, or you spawn one from another.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • On a distributed system (which is auto-scalable) does it still make sense to explicitly warm-up the app so as to ensure that the methods are compiled ? – TheLostMind Apr 02 '16 at 10:58
  • @TheLostMind distributed or not, whether you need to manually warm up the code depends on whether the performance before warmup is acceptable and whether you can warmup the application before it is used, i.e. is the service started long before it is used. It is fairly rare that you care IMHO, one area it really helps is in low latency trading systems as 10,000 orders is a lot of orders to wait for before you perform at best speed. esp if those order are for millions each and you restart your servers regularly. – Peter Lawrey Apr 02 '16 at 11:02
  • hmm I see.. That makes sense. I was just trying to say - if your app is deployed on (say) AWS, it will be difficult to warm up code for each new instance / JVM that gets created based on load – TheLostMind Apr 02 '16 at 11:05
  • 3
    @TheLostMind You don't want to accept that for the first 10 billion in orders per day or per week you will not be getting best speed/price. A slow order could be costing you 0.002 % of the notional which doesn't sound like much but it could be $20,000 per week. – Peter Lawrey Apr 02 '16 at 11:05
  • 2
    @TheLostMind provided the instance are loaded before you need them, e.g. even 10 seconds or a minute before, you can spend that time warming up the code, or at the very least do some basic tests of correctness. The biggest hit is the first time a class loads, so just hitting the code once might be enough. – Peter Lawrey Apr 02 '16 at 11:07
  • I see.. I will try it and see the performance difference. Thanks :) – TheLostMind Apr 02 '16 at 11:10
  • @TheLostMind the performance difference only matters if you are looking at the latency distribution. If you look at the throughput of many calls, you won't see much difference. – Peter Lawrey Apr 02 '16 at 11:11
  • Why do you still mention CompileThreshold when I've already [shown](http://stackoverflow.com/questions/35601841/how-does-the-jvm-decided-to-jit-compile-a-method-categorize-a-method-as-hot/35614237#35614237) it plays no role in modern JDK. Try out a simple test with `-XX:CompileThreshold=1` and `-XX:CompileThreshold=100000000` – apangin Apr 02 '16 at 11:17
  • I see.. Makes sense.. Sometimes I wish there were ways to clone a brain :P. – TheLostMind Apr 02 '16 at 11:17
  • 3
    BTW, warm-up is not only about JIT-compilation. I would say it is not about JIT at all in large server applications. The only way to determine that the warm-up phase is over is to watch application-specific performance metrics coming to steady state. – apangin Apr 02 '16 at 11:28
3

To start off, you should not worry about warming up / force- compiling methods in production environment because lets face it - JIT is smarter than us :P.

How shall I determine the number of times a test should run before my JVM is fully warmed-up?

On Java 8 on a mac, it takes about 256 iterations for a method to be JIT compiled (Assuming the method is capable of being JIT compiled). This number could vary from one JVM to another.

Does this change JVM to JVM? I mean is it possible that if I'm able to warm-up my JVM by running 1000 iterations then someone else might end up needing more or less?

This might change from JVM to JVM. It is not safe to assume that this number would remain the same for different JVMs.

Is running tests the only way to warm-up the JVM?

Well, if you are trying to benchmark something, then yes. You should let the JVM optimise what it can (by using warm-up runs) and then measure performance.

When should I warm-up the JVM? I mean the frequency. Should I do it every-time I'm stopping and starting my application or just once after rebooting my servers?

Every-time you want to benchmark (i.e, at JVM / app startup). I see no reason for doing this in production environment. Note that in some cases JIT can actually prefer an interpreted method over a compiled method if it finds a flaw in its assumptions.

TheLostMind
  • 35,966
  • 12
  • 68
  • 104
  • I want to vote your answer but it is not letting me. –  Apr 02 '16 at 07:59
  • 1
    @MissMeme - No problem Madamji :).. You should install [JitWatch](https://github.com/AdoptOpenJDK/jitwatch) to see what is being compiled by JIT and after how many runs etc etc – TheLostMind Apr 02 '16 at 08:01
  • @ThLostMind Thanks for the response. I'll install JitWatch. :) –  Apr 02 '16 at 08:03
  • @MissMeme - Also check [this](http://stackoverflow.com/questions/18345089/what-does-compilethreshold-tier2compilethreshold-tier3compilethreshold-and-tie). *Thresholds* can be dynamically adjusted – TheLostMind Apr 02 '16 at 08:07
  • 2
    I am pretty sure the `-XX:CompileThreshold=10000` even on a mac. – Peter Lawrey Apr 02 '16 at 10:45
  • @PeterLawrey - Yes. Just checked. It is set to 10000 yet C1 is compiling a method of mine at level 3 when it is run for 256 times :) – TheLostMind Apr 02 '16 at 10:50
  • @TheLostMind I guess it's not clear what the OP means by warming up, but I assume this is done for a reason and you want to best warmup you can get. – Peter Lawrey Apr 02 '16 at 10:53
  • @PeterLawrey - I think by *warming up* she means ensure that methods are compiled by JIT so that she can benchmark her apps performance better. – TheLostMind Apr 02 '16 at 10:56
  • @TheLostMind so if she is benchmarking she should warm up the code to the degree which would be realistic in production or her target system. It is tricky to assume you want to prevent C2 from kicking in. – Peter Lawrey Apr 02 '16 at 10:59
  • @PeterLawrey - That's true.. But what *could be realistic* in production? – TheLostMind Apr 02 '16 at 11:00
  • @MissMeme - You should look (and feel free to accept :P) at Peter Lawrey's answer. He is one of the best on SO when it comes to JVM / JIT :) – TheLostMind Apr 02 '16 at 11:06
1

How shall I determine the number of times a test should run before my JVM is fully warmed-up?

  • measure both latency and throughput of your application logic and see when it levels out
  • trace JIT behavior with -XX:+PrintCompilation

Every application is different, so it's best if you gather your own data. Based on that data you can then make further decisions.

the8472
  • 40,999
  • 5
  • 70
  • 122