annoying gaps playing Java2D games

Have anyone suffered from this??

when I’m playing my own Java2d developed games or games from other people, like:

http://www.java-gaming.org/index.php/topic,22072.0.html
http://viruseffect.com/demo.php

There is some kind of delays of around half second or less, but they make the playing experience very annoying. They happen in intervals beetwen 10 or 20 seconds (every 15 seconds moreorless, the gap happens).

Any idea? I’ve tried hundreds of different implementations and I think it isn’t a matter of hardware.

Thanks in advance

Noticed the same intermittently in my car game. Very annoying, haven’t found either cause or solution.
Seems like it does it once near the beginning of the game, and then it’s ok for the rest of the app lifecycle…
Testing virus effect, not noticing it in the tutorial at least…

This is probably caused by the garbage collector + slow machine

I think you are right,

I have tried the applets in my laptop (Core2Duo 1.66Ghz, 2Gb RAM, good graphic card) and it runs smooth

Anyway, my desktop computer is not slow (AMD athlon 64 2.21Ghz, 2Gb Ram, good graphic card).

They both have newest java version.

Maybe there is some way to tune the garbage collector, because it is a really annoying effect, unnaceptable for a game. Every 15 or 20 seconds a “micropause” of half a second.

Before jumping to conclusions, add this to the JVM arguments:

-verbose:gc

There are a lot of ways to tune the GC. Pick the collector that performs best. That might mean that the overall performance might be a tad slower, but keeping the collection times below 10ms. Try the concurrent collectors and monitor the verbose output.

maybe to much Threads created, someone could log concurrent threads with jconsole 32 bits (im running jdk 64bits)?

You can create dozens of threads per second.

Thanks for your piece of advice, definately is not gc:

[GC 3374K->2478K(5056K), 0.0002872 secs]
[GC 3374K->2478K(5056K), 0.0002363 secs]
[GC 3374K->2523K(5056K), 0.0015362 secs]
[GC 3419K->2551K(5056K), 0.0011423 secs]
[GC 3447K->2525K(5056K), 0.0005758 secs]
[GC 3421K->2524K(5056K), 0.0002931 secs]
[GC 3420K->2525K(5056K), 0.0003107 secs]
[GC 3421K->2525K(5056K), 0.0002732 secs]

And they do not coincide in time (gaps and gc cycle, gaps are more frequent)

I’m going to try updating DirectX and drivers, although I’m quite sure they are up to date.

Edit: if it is useful, I attach a capture of the commented effect (the video is a litle bit jittered but it is due to capture software, in any case the gaps are very noticeable if you look up the red bar [down left corner])
http://www.holtin.com/temp/a/capture-1.avi

Let’s have a look at your animation loop.

For sure, the problem is that not only mine fails but also almost of the other people games ( like for example: http://www.gudradain.byethost12.com/geomwar.html ).
In any case:

The timer is like this:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package game.port;


public class GameTimer extends Thread{
    private TimerListener listener;
    private boolean stoped = false;
    private long lastNanos,currentNanos;
    private long durationNanos, neededNanos;

    public GameTimer(TimerListener listener, int fps) {
        this.listener = listener;
        durationNanos = 1 * 1000 * 1000 * 1000 / fps;
        setPriority(MAX_PRIORITY);
    }
    
    @Override
    public void run(){
        while(!stoped){
            lastNanos = System.nanoTime();
            listener.doTimerAction();
            currentNanos = System.nanoTime();
            neededNanos = durationNanos - (currentNanos - lastNanos);
            if (neededNanos > 0){ 
                try {
                    sleep(neededNanos / (1000 * 1000), (int) (neededNanos % (1000 * 1000)));
                } catch (InterruptedException ex) {
                }
            }
            
        }
    }
    
    public void end(){
        stoped = true;
        interrupt();
    }

}

And the render part is like follows, in tick I do the logic and render the things using g, it is not problem of Lost buffer because I do not see the system.out in the console.

 public void doTimerAction(){
        if (! canvas.isVisible()) {return;}

         try {
           do {
            do {
              g = (Graphics2D)strat.getDrawGraphics();
              //render
              tick();
              //end render
              g.dispose();
              g = null;
            } while (strat.contentsRestored());
            strat.show();
          } while(strat.contentsLost());

        } catch(IllegalStateException e) {
          System.out.println("Lost buffer. recreating it. please wait...");
          try {
            Thread.sleep(500);
          } catch (InterruptedException ex) {}
          canvas.createBufferStrategy(2);
          strat = canvas.getBufferStrategy();
        }
    }

Smooth here. Why don’t you open your taskmanager, not running any game, and see whether there are spikes when idling.

CPU never gets higher than 30%, range from 4% to 25%, the peaks(of about 30%) in the graphic does not coincide with java gaps.

Do not worry I’m going to give up, I will try with my others computers and I will inform you.

PS: I forgot to beg your pardon for my english.

If you use thread.sleep in the main cycle then im pretty sure that is the cause cause i have an athlon64 cpu too and the thread sleep is very inconsistent, it can sleep 0ms and then on next step even 60ms with same argument, i think the only way to have smooth frame rate is to use thread.yield in the waiting logic, but it makes seem like java uses 100% of processor but it actually won’t use it that much and other programs can do anything while thread.yield happens.

I also thought that the problem could be related with getCurrentMillis and sleep precission but I switched to getNanos and to LockSupport.parkNanos respectively, and the problem remains (I check the precission and it’s OK [normally no more than 5 millis deviation and the peaks do not coincide with the gaps]).

Even using only Thread.yield and consuming 100% CPU (and switching the game logic to delta time based logic) the problem remains. I pass the antivirus (no virus at all), disable all programs, etc… nothing

I surrender, I have tried with other computers(some, less powerful) and I have not observed the problem. I do not know if it is due to my configuration or hardware.

Track the values of System.nanoTime().

Does it go back in time?

Never. But I skip sleeping negative values anyway, or the question is not related with that??

no System.currentTimeMillis is inacurate but wont cause such problem and is the most robust (only one reliable) timer I know (far to be perfect but without no issue over all java version except a high granularity), but sleep could done bad artefact especially the way you used it in your main loop but not that long…

some times ago ATI & JOGL card was giving such problem, does it happend on all kind of game or only opengl ?

If you have a multi-core CPU with frequency throttling, your cores can get out of sync. System.nanoTime() on core A can be different from System.nanoTime() on core B. As 1 thread gets shuffled among the available cores System.nanoTime() get make jumps both into the future and into the past. If you’re waiting for a certain moment (like: this.nextStep or whatever) it might happen instantly, or you might have to wait unreasonably long.

Really?! I would have thought that the timing would always come from the same core so it can be consistent but I guess you can’t expect that.

System.nanoTime() is per core
System.currentTimeMillis() is system wide