1

I am using Intellij to program Java.

I am currently trying to make a top down tile based shooter.

My issue is that my game, after approximately 2 minutes, crashes with a popup saying "Java(TM) Platform SE Binary has stopped working. I recorded the time it took for it to crash 3 times: 1m57s, 1m59s, 1m58s.

The game is in a very simple state right now and I am not sure what could be causing the crash. All of the relevant code is in just two classes: GameFrame.java (extends JFrame) and GamePanel.java (which extends JPanel).

GameFrame.java:

    package net.magnusfrater.tds.game;

    import javax.swing.*;

    public class GameFrame extends JFrame {

        public static final int width = 1000;
        public static final int height = width / 16 * 10;

        private GamePanel gp;

        public GameFrame () {
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setSize(width,height);
            setResizable(false);
            setLocationRelativeTo(null);

            setTitle("Time Based Fast Paced Top Down Shooter Demo");

            gp = new GamePanel();
            add(gp);

            setVisible(true);
        }

        public static void main (String[] args) {
            GameFrame gf = new GameFrame();
        }
    }

GamePanel.java

    package net.magnusfrater.tds.game;

    import net.magnusfrater.tds.input.Keyboard;

    import javax.swing.*;
    import java.awt.*;

    public class GamePanel extends JPanel implements Runnable {

        //panel
        private Thread thread;
        private static boolean running;
        private boolean fpsLock;

        //input
        private Keyboard kb;

        //game
        private Game game;

        public GamePanel () {
            //panel
            thread = new Thread(this, "Time Based Fast Paced Top Down Shooter Demo");
            running = true;
            fpsLock = true;

            //input
            //kb = new Keyboard();
            //addKeyListener(kb);

            //game
            //game = new Game(1);

            thread.start();
        }

        public void run () {
            long iTimeNS = System.nanoTime();
            int tickRate = 60;
            long ns = 1000000000 / tickRate;

            int ups = 0;
            int fps = 0;

            long iTimeS = System.nanoTime();
            long s = 1000000000;

            while (running) {

                long fTimeNS = System.nanoTime();
                if (fTimeNS - iTimeNS >= ns){
                    iTimeNS = System.nanoTime();

                    tick();
                    ups++;

                    if (fpsLock){
                        repaint();
                        fps++;
                    }
                }

                if (!fpsLock){
                    repaint();
                    fps++;
                }

                long fTimeS = System.nanoTime();
                if (fTimeS - iTimeS >= s){
                    iTimeS = System.nanoTime();

                    System.out.println("ups: " + ups + "\tfps: " + fps);

                    ups = 0;
                    fps = 0;
                }

            }

            System.exit(0);
        }

        public void tick () {
            if (kb != null)
                kb.tick();

            if (game != null)
                game.tick();
        }

        @Override
        public void update (Graphics g) {
            paint(g);
        }

        @Override
        public void paint (Graphics g) {

            g.setColor(Color.WHITE);
            g.fillRect(0,0,GameFrame.width, GameFrame.height);

            //if (game != null)
                //game.paint(g);
        }

        public static void quitGame () {
            running = false;
        }
    }

I originally thought that the issue was because of the way that I was loading images for spritesheets or maybe the way I was loading text files for the level design but after reworking both of those, the issue remained.

That left me curious and a little bit fed up so I tried finding out more about the explanation for the crash. First I read more from the popup but it didn't say anything useful: (See below)

Second I looked at the exit code given by Intellij: (See below)

I looked up what exit code 255 was but there wasn't anything useful. The best explanation I could find was that exit code 255 meant that the real exit code was out of range: (See below)

I was out of ideas at this point so I just started plain old googling everything I could think of. The problem with googling "Java(TM) Platform SE Binary has stopped working" is that almost every suggested link is a question about Minecraft. Limiting my search to Stack Overflow yielded me some results, but nothing conclusive. Some of the fixes I found were stuff I already tried (such as not handling input streams properly, not handling buffered reader properly, not disposing of elements, etc). I found these links but none of them were truly related to my issue:

  1. (See below)

  2. (See below)

  3. (See below)

  4. (See below)

  5. (See below)

  6. (See below)

The last fix I tried was to re-install Java SE Development Kit 8u101 AND Java SE Development Kit 8u102. I then restarted Intellij. I then restarted my computer.

Nothing worked.

At this point I think I'm just dumb. I've overlooked something easy I can tell. What am I missing?

(ps~ This is a possibly related issue. So if I run my game with almost no content in it with the fps not locked to 60, I get really absurd numbers of frames per second. I didn't think that fps as high as 7,000,000 was possible. I think. I don't know. Have I programmed that wrong as well? Here is a related picture of my ups/fps output: [see below])

(SEE HERE) So Stack Overflow doesn't allow members with a score within a certain threshold post more than 2 links and allows absolutely no posting of images. So here is a link to a google doc with all of the links and images I mentioned above: https://docs.google.com/document/d/1XrBuVio19GmkFz0EfRzXVp5AJmM5zPfVO6vK3oS3Eaw/edit?usp=sharing

  • You might want to put a sleep into that loop, otherwise you'll just overload your CPU with continuous calls to `System.nanoTime()`. – Dawood ibn Kareem Sep 16 '16 at 04:10
  • I almost always run it with the fps locked at 60 (especially since this issue). Quick question though: am i hurting my CPU by running it so hard? – goddtriffin Sep 16 '16 at 04:13
  • I doubt whether you're hurting your CPU, but you're almost certainly making your JVM crash. Is there any point in running the loop more often than once per frame? And if not, consider having a sleep in there of about 1/60 of a second. – Dawood ibn Kareem Sep 16 '16 at 04:14
  • Would it still make the JVM crash if I locked it at 60? Sorry if I'm pestering, but I always thought that using sleep was improper in a game loop. – goddtriffin Sep 16 '16 at 04:15
  • I don't know about improper. I believe that this is what you'll need to do to make this work. But I'm not a game developer - most of my work to date has been on business applications. Why don't you try my suggestion, and see if it works. If it makes the game unplayable, then try something else. But it sounds to me like it's pretty unplayable as it is. – Dawood ibn Kareem Sep 16 '16 at 04:24
  • Ok so I put "thread.sleep(10)", "thread.sleep(5)", and "thread.sleep(1)" at the bottom of the "while (running)" loop and the only thing that changed was that the ups/fps never once reached 60 for any of the tries. The game still ended up crashing after approximately 2 minutes (instead of being just under 2 minutes however, it crashed just over 2 minutes in the 2m0s to 2m10s range). – goddtriffin Sep 16 '16 at 04:25
  • Then I don't know how to fix it, sorry. It could be something odd in the `Game` class or the `Keyboard` class, which you haven't shown. – Dawood ibn Kareem Sep 16 '16 at 04:30
  • It's okay, thank you very much for your help. I know for a fact that it's not the keyboard class nor the game class that is the issue because I completely commented out any mention of both of them in GamePanel.java and the issue continued. But thanks regardless. – goddtriffin Sep 16 '16 at 04:35
  • Try reading up on the answers here http://stackoverflow.com/questions/351565/system-currenttimemillis-vs-system-nanotime It may help with your problem. My understanding is you should only call System.nanoTime() once per game update, and you have 4 calls to it. – Hypnic Jerk Sep 16 '16 at 05:07
  • I never thought of looking up the cost to that call. Well I looked through that link, and I changed my code so that I called System.nanoTime() once when I begin the thread for the initial 'iTime' field and then once every subsequent game loop (I call nanoTime() once at the beginning of the 'while (running)' loop and just reuse it throughout). The issue continued sadly and it still occurred after approximately 2 minutes of game time (1m59s). – goddtriffin Sep 16 '16 at 05:31
  • How are you running this? Have you tried running this outside IntelliJ? What is your run configuration (arguments like -Xmx)? Are you launching it in debug mode? If you increase the -Xmx does it run longer? – dlamblin Sep 16 '16 at 07:31
  • Report a bug to Oracle. – Meo Sep 16 '16 at 09:14
  • When the JVM crashes it produces a dump with information why it crashed. What's written in your dump ? – Svetlin Zarev Sep 16 '16 at 11:52

1 Answers1

1

Try and set your -Xmx to something like 2G and see if it runs longer. If so, something is allocating memory and maybe you have that other setting set that exits instead of garbage collecting for some reason.

Also, try changing your code to limit things using Guava's RateLimiter.

…
// class level
final RateLimiter frameLimiter = RateLimiter.create(60.0);
final RateLimiter outputLimiter = RateLimiter.create(1.0);
…
// in run method
while (running) {
  frameLimiter.acquire();
  repaint();
  fps++;
  if (outputLimiter.tryAcquire()){
    System.out.println("fps: " + fps);
    fps = 0;
  }
}

I've removed ups and tick(). You should do your work after repainting and I don't think you want to do more work than needed for the next frame, which at the soonest should be at your max rate. Later you'll need to add logic to handle skipping work when frames are being skipped. I might make more sense to increment the fps within repaint. You could put the output in its own thread and only acquire that limiter if you synchronized the increments and resetting of fps.

dlamblin
  • 43,965
  • 20
  • 101
  • 140