LWJGL Memory leak/Function running many times

Hi,

Something in my code is making my draw function run tons of times, which is causing a memory leak, here is the draw code for the menu:

	   public void draw() {
	       Color.white.bind();
	       loadText();
	       System.out.println("this shouldnt be running more than once"); // what i am using to test
	       backg();
	       handleInput();
	          font.drawString(Display.getWidth() / 2 - 150, Display.getHeight() - 100, "Play", colorSelected);
	          font.drawString(Display.getWidth() / 2 - 50, Display.getHeight() - 50, "Quit", colorSelected2);
			if(currentChoice == 0) {
				colorSelected = MenuButton.COLOR_SELECTED;
				colorSelected1 = MenuButton.COLOR_UNSELECTED;
				colorSelected2 = MenuButton.COLOR_UNSELECTED;
			}
			if(currentChoice == 1) {
				colorSelected = MenuButton.COLOR_UNSELECTED;
				colorSelected1 = MenuButton.COLOR_UNSELECTED;
				colorSelected2 = MenuButton.COLOR_SELECTED;
			}
			font.drawString(20, Display.getHeight() - 30, Game.VERSION, Color.black);
	       cleanUp();
	   }

Thanks,

  • Dan

You do know that draw will be called every frame correct? It’s not causing a memory leak. What do you except to happen?

G’day Dan,

Obviously your draw function is meant to run ‘tons of times’ per second within your game loop, but are you implying that your draw method is being run more than once per loop? Or is one call to draw() resulting in draw() being called again and again? The only thing I can suggest is that you need to scour your code for calls to draw(), and ensure that it is only being called once, and is not being recursively called from within draw() itself.

As for the ‘memory leak’, are you creating new objects or similar during your draw() method? Are these objects being properly disposed or handled? Ideally, you should avoid object creation during a loop; it is generally bad news. If you have any resources that are repeatedly used within a loop, then create them outside of the loop and hang on to them. Assuming you have plenty of memory at your disposal, it could be favourable to create an object/allocate memory once, as opposed to continually re-creating and disposing of it. Just as a very, very wild guess, have a look at your loadText() method; what is happening in there?

Ok Ill have a look at that thanks, as for loadText(), this is all its doing:

	public void loadText() {
		glEnable(GL_BLEND);
	    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	}

and this is cleanUp()

	public static void cleanUp() {
		glDisable(GL_BLEND);
	}

Thanks,

  • Dan

The line where memory leak happens would be helpful…

Yeah well thats the problem, I’m trying to find out where the problem is or why its happening

this is my state code, this could be causing it:

	// Render Game States
	private void render() {
		switch (state) {
		case INTRO:
			IntroState.draw();
			state = State.FADING;
			break;
		case FADING:
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
            state = State.MAIN_MENU;
			break;
		case MAIN_MENU:
			menu.draw();
			break;
		case GAME:
			gameState.Background();
			player.draw();
			enemy.draw();
			for (Particle c : particleList) c.draw();
		//	gameState.draw();
			break;
		case RAND:
			new RandomTerrain();
			break;
		}
	}

Thanks,

  • Dan

You just said that you’re getting memory leak. That means you’re getting an exception somewhere. Post that exception and the code corresponding that exception here please.

There doesn’t seem to be anything remarkable about your code (other than the debugging println statement which would make things veeeery slow). Only thing that surprises me is that you do not seem to want your draw procedure to run each frame. When do you want draw() to be called? Also, memory leaks are quite hard to cause in Java, so why do you think you have one here?

So nothing much has changed since this post: http://www.java-gaming.org/topics/lwjgl-how-to-delay-between-states/32016/msg/298308/view.html ??? Anyway, I won’t harp on about it.

I can potentially see a problem here:

Unless your RandomTerrain constructor changes the state, or you do it elsewhere, you will be stuck in the ‘RAND’ state, and will continuously create RandomTerrain objects.

You could always do some profiling to determine where your memory is being eaten.

:smiley: The only case when I cause memory leak is when I don’t handle lists properly and they receive too many objects :smiley:

How do you know that there is a memory leak? What code or resources have you used to find this problem? Also, that fading code looks a little strange…

Well, in the RandomTerrain code, it runs fine at constant memory level, however in the menu state, the memory keeps going up and up until it crashes, also, it only seems to leak on some computers, on others it just goes up and down, like from 2.5GB to 3.5GB and back again not sure why.

Thanks,

  • Dan

What is the line where the error occurs? Or does it simply crash?

Have you tried calling glGetError();?

Or to back up even further: why do you think you have a leak?

Well this is the error given when it crashes:

Exception in thread "main" java.lang.OutOfMemoryError
	at sun.misc.Unsafe.allocateMemory(Native Method)
	at java.nio.DirectByteBuffer.<init>(Unknown Source)
	at java.nio.ByteBuffer.allocateDirect(Unknown Source)
	at org.lwjgl.BufferUtils.createByteBuffer(BufferUtils.java:60)
	at org.newdawn.slick.opengl.PNGImageData.loadImage(PNGImageData.java:96)
	at org.newdawn.slick.opengl.CompositeImageData.loadImage(CompositeImageData.java:62)
	at org.newdawn.slick.opengl.CompositeImageData.loadImage(CompositeImageData.java:43)
	at org.newdawn.slick.opengl.InternalTextureLoader.getTexture(InternalTextureLoader.java:292)
	at org.newdawn.slick.opengl.InternalTextureLoader.getTexture(InternalTextureLoader.java:254)
	at org.newdawn.slick.opengl.InternalTextureLoader.getTexture(InternalTextureLoader.java:200)
	at org.newdawn.slick.opengl.TextureLoader.getTexture(TextureLoader.java:64)
	at org.newdawn.slick.opengl.TextureLoader.getTexture(TextureLoader.java:24)
	at ms.nac.spacejunk.states.IntroState.texture(IntroState.java:17)
	at ms.nac.spacejunk.main.Game.<init>(Game.java:77)
	at ms.nac.spacejunk.main.Game.main(Game.java:157)
AL lib: (EE) alc_cleanup: 1 device not closed
java.lang.OutOfMemoryError

Thanks,

  • Dan

There is a loop that is creating objects but not destroying them causing Java to run out of memory. It definitely isn’t a memory leak. A quick solution would be to increase the memory…

[icode] -Xmx1024m [/icode]
Putting this within the VM Arguments or before you run your .jar can help…

I am suspecting your “Particle” class, since this is the only place I actually see some kind of a loop that can generate a lot of Objects. I would look around your code to places in where you are creating a lot of objects and start to comment out the loops, or if you are familiar with how to use a profiler, then you can check to see which Objects are taking up the most space in memory and are not getting collected by the Java GC.

Do not simply increase memory limit and pray.

Figure out what went wrong; if you simply need more memory then fine, otherwise raising the limit won’t help.
That error tells me that you are creating lots of Textures and not disposing / destroying them and thus “leaking” memory.

Disclaimer: I don’t use slick, and I don’t know what’s still current, but this is similar to what davedes said here: http://slick.ninjacave.com/forum/viewtopic.php?f=3&t=4652
Also check through those lines listed in that stacktrace in the slick source: https://bitbucket.org/kevglass/slick

This is why I’m “annoying” person to most people. Sorry I’m about to say this… but…

Are you fucking serious?
I asked the line at which the error occurs like 2 or 3 or more days ago. Still no answer. How do you expect to get help, if you can’t even show us where the error occurs?

From the error message, it is quite clear that you’re allocating memory for some kind of image. You need to stop loading images every time you update/render game.

My question would be: what’s with the constructor ()? If this is happening after many frame, then a new Main is being made many times.