Hi !
Featured games (90)
games approved by the League of Dukes
Games in Showcase (794)
Games in Android Showcase (234)
games submitted by our members
Games in WIP (864)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Tips for reducing frame rate spikes due to JIT early in a game?  (Read 34767 times)
0 Members and 1 Guest are viewing this topic.
Offline ashen

Junior Newbie

« Posted 2016-08-12 14:38:55 »

For roughly the first 30-40 seconds in my main 'play game' state there are a series of severe spikes in the execution time of individual frames. These occur very roughly about 5 seconds apart.  Sometimes a spike can cause a frame to be almost 1 second.  At about 30 seconds the spikes start to reduce in severity until the game is running with no noticeable issues.  (PC is dual core, 3.5Ghz, 64Bit, Java 8, 8 GB RAM).

One severe spike can actually be triggered 100% of the time by clicking on a particular button in the game, but only on the very first click.  The spike will not happen again until the game is closed and restarted. I analyzed the code in this button and found nothing that could obviously cause such a big spike. 

This made me think that these spikes are due to methods in my code being compiled by the JIT compiler.  So using the ASM library I wrote a simple test that parses a JAR containing game class files and writes out the number of bytecode instructions for each method. 

The largest method in my main game loop is 2980 instructions while other larger methods are 1891, 1446 and 1037, 1028.  I've read that Hotspot compiles methods up to about 8000 instructions, so I assume these are being compiled ok. 

So I'm wondering if it's worth the effort of say getting all methods down to a max of 500 instructions or so?  I guess that the smaller the methods the faster they can be compiled and therefore a reduction in the severity of spikes?  On the other hand, the event handler for the button that causes a spike is only 45 instructions. 

I've also thought about doing a 'warmup' period where I run the full game loop for say 10 seconds but with input disabled / blank display, just to allow the spikes/compilation to occur without annoying the player.  Right now, I would actually say that a delay of 10 seconds would be less annoying to the player than having to deal with frame spikes while trying to play the game. Is this a reasonable/common thing to do?

Of course, let me know if you think its not the JIT compiler at all.  Thanks.
Offline 65K
« Reply #1 - Posted 2016-08-12 14:55:02 »

Do not bother counting byte code instructions and by no means "optimize" code by reducing method sizes based on guesses what the compiler might do.
Use an ordinary profiler to search for suspicious behaviour, bad performance, memory leaks, etc.

Lethal Running - a RPG about a deadly game show held in a futuristic dystopian society.
Offline ashen

Junior Newbie

« Reply #2 - Posted 2016-08-12 15:02:55 »


I've been using VisualVM for profiling.  When the spikes occur the garbage collector was at 0%.  The 'sawtooth' heap pattern showed reclaiming of memory only every 20 seconds or so but the GC remained at 0% at all times.
I also tried passing Xms and Xmx JVM arguments of 1024 / 2048 to ensure the heap isn't resized.    This worked, VisualVM showed no change to the heap size, but the frame large spikes continued to occur as described above.

I'm not going to try guessing what the compiler might do, but regardless, isn't it a good idea in Java to have many smaller methods both for code maintenance and performance?

Do you think the spikes are caused by the JIT compiler or something else?
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline 65K
« Reply #3 - Posted 2016-08-12 15:09:16 »

isn't it a good idea in Java to have many smaller methods both for code maintenance and performance?
For performance, no. For maintenance, yes, as long as methods aren't cut into such small pieces that you get the opposite effect: less readability

Do you think the spikes are caused by the JIT compiler or something else?
Nobody can tell without examining your running game.

Lethal Running - a RPG about a deadly game show held in a futuristic dystopian society.
Offline Icecore
« Reply #4 - Posted 2016-08-12 16:24:17 »

warm-up spikes can be fixed with JVM start arguments, (custom build ^^)
Try this:

+maybe search more in docs

up: it also may be caused by static fields initialization (new static array list 1000) - in middle of frame
can be fixed by calling all - heavy static data classes - in init phase

Last known State: Reassembled in Cyberspace
End Transmission....
Journey began Now)
Offline ashen

Junior Newbie

« Reply #5 - Posted 2016-08-13 02:04:56 »

@Icecore, Thanks, I'll try the server and escape analysis flags.  There are so many to read up on, I guess it's very game specific as to what will have noticeable effects or not.

Good point about static variable initialization, I'll have a look at that too.
Offline princec

« JGO Spiffy Duke »

Medals: 1096
Projects: 3
Exp: 20 years

Eh? Who? What? ... Me?

« Reply #6 - Posted 2016-08-13 07:54:23 »

Try using two-tier compilation with the server VM.

Escape analysys won't do anything for you.

Cas Smiley

Offline CodeMason
« Reply #7 - Posted 2016-12-26 15:23:23 »

What is two tier compilation for the server VM?  I found this ( but that looks like it is only for the client VM?
Offline Roquen

JGO Kernel

Medals: 518

« Reply #8 - Posted 2016-12-26 17:07:43 »

client/server VM is just a 32-bit VM thing.  Everything's server VM for 64-bit.
Offline Riven

« JGO Overlord »

Medals: 1364
Projects: 4
Exp: 16 years

Hand over your head.

« Reply #9 - Posted 2016-12-26 17:42:14 »

Shouldn't we go back to the original post and wonder whether all assertions are correct?

A 1000ms JIT pause is highly unlikely, given that the JIT does its work incrementally.

I bet it's a code path that the OP isn't expecting, triggering a lot of disk I/O, the incorrect initialisation of a data-structure, etc etc.

If you simply profile your code (and use System.currentTimeMillis / System.nanoTime to confirm your suspicions) you'll most likely find the culprit quite quickly.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings!
Pages: [1]
  ignore  |  Print  

hadezbladez (3132 views)
2018-11-16 13:46:03

hadezbladez (1142 views)
2018-11-16 13:41:33

hadezbladez (3101 views)
2018-11-16 13:35:35

hadezbladez (623 views)
2018-11-16 13:32:03

EgonOlsen (3911 views)
2018-06-10 19:43:48

EgonOlsen (4381 views)
2018-06-10 19:43:44

EgonOlsen (2617 views)
2018-06-10 19:43:20

DesertCoockie (3436 views)
2018-05-13 18:23:11

nelsongames (3556 views)
2018-04-24 18:15:36

nelsongames (4606 views)
2018-04-24 18:14:32
Java Gaming Resources
by philfrei
2019-05-14 16:15:13

Deployment and Packaging
by philfrei
2019-05-08 15:15:36

Deployment and Packaging
by philfrei
2019-05-08 15:13:34

Deployment and Packaging
by philfrei
2019-02-17 20:25:53

Deployment and Packaging
by mudlee
2018-08-22 18:09:50

Java Gaming Resources
by gouessej
2018-08-22 08:19:41

Deployment and Packaging
by gouessej
2018-08-22 08:04:08

Deployment and Packaging
by gouessej
2018-08-22 08:03:45 is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!