0

Edit(Solution): I was deriving a font each time the paintComponent method would be called which would then create a new font object each time using up several gigabytes of memory.

I'm currently developing a little game as a university project and its going pretty good but i stumbled upon some confusing behaviour that is going on when I call repaint(). The game itself is really simple. There is just a player that can move around, jump and a little text displaying fps/ width and height of the window.

I have two threads. One is executing the game logic and one is painting/repainting.

I noticed that my application would consume up to several gigabytes of memory over time. After further investigation it seems that this behaviour is caused by calls go the drawString method in the paintComponent method which is called when I repaint the screen (a JPanel).

The behaviour stays the same even if I limit the times the repaint method is called per second.

But if I comment out the calls to drawString method my application suddenly only consumes around 20 to 50 megabytes of memory.

Here is what a call looks like:

g.drawString("FPS: " + this.getFPS() + " width: " + this.getWidth() + " height: " + this.getHeight(), 10, 15);

I inspected the memory behaviour with Java VisualVM. Maybe someone has an idea what is going on here.

  • *"Memory leak?"* No. Not unless there is an `OutOfMemoryError`. Anything short of that is premature optimization, given the JVM only runs GC when it feels it is necessary to do so, – Andrew Thompson Mar 03 '17 at 15:38
  • What about if you simplify the line to just something like `g.drawString("test", 10, 15)`. Do you still get the problem? Maybe getFPS() is the problem. – Steve Smith Mar 03 '17 at 15:40
  • I just have the feeling that painting text on the screen should not consume gigabytes of memory. The issue persists even if i do something like 'g.drawString("hello", 5, 5)' It also seems that the memory consumption stops after around 3 minutes but then the application freezes. – PurifyPioneer Mar 03 '17 at 15:47
  • Are you clearing the canvas before you paint or removing old drawn strings? I could see this behaviour happening if you are continuously creating new elements but never removing references to old ones. – HedonicHedgehog Mar 03 '17 at 15:50
  • Mh. im just calling repaint but not specifically clearing the frame. How would I do this, because 'removeAll()' doesnt seem to produce the desired result. – PurifyPioneer Mar 03 '17 at 15:53
  • I think Andrew might have it right actually. Unless you are receiving an OutOfMemoryError, there is likely no problem. Java's garbage collection is lazy and won't retrieve space unless it needs it. You might experiment with changing the max heap size for your program with JVM settings (-Xmx) to see if that is the case – HedonicHedgehog Mar 03 '17 at 16:04
  • I would actually be fine with it using as much memory as it wants but the application crashes or slows down extremly after a few minutes for no apparent reason except drawString. – PurifyPioneer Mar 03 '17 at 16:30
  • maybe you are creating some color objects etc - one simple line doesnt tell us anything - you wanna put a verifiable program up with the wrong behavior? fine – gpasch Mar 03 '17 at 21:31
  • http://pastebin.com/V4Drsk6H Thats the whole painting method. As you can see i commented out all g.drawString calls and the application does only consume around 10 to 50 mb of ram. If I activate any of these calls, does not matter which one, the faulty behaviour starts happening and the application uses gigabytes of ram and then crashes/gets extremly slow after a few minutes. – PurifyPioneer Mar 03 '17 at 23:40
  • You can [profile](http://stackoverflow.com/q/2064427/230513) to learn more. – trashgod Mar 04 '17 at 00:13

0 Answers0