Application memory usage and direct buffer memory error?

I’m having trouble tracking down why memory usage is so high and I keep getting a direct buffer memory error. Before we start here is the relevant output.

SEVERE: Uncaught exception thrown in Thread[jME3 Main,5,main]
java.lang.OutOfMemoryError: Direct buffer memory
	at java.nio.Bits.reserveMemory(Bits.java:693)
	at java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:123)
	at java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:311)
	at com.jme3.util.BufferUtils.createByteBuffer(BufferUtils.java:997)
	at com.jme3.texture.plugins.AWTLoader.load(AWTLoader.java:155)
	at com.jpony.UI.Control.setImage(Control.java:394)
	at com.jpony.UI.Label.draw(Label.java:138)
	at com.jpony.UI.Label.setSize(Label.java:181)
	at com.jpony.UI.Control.resize(Control.java:376)
	at com.jpony.UI.UserInterface.resize(UserInterface.java:264)
	at com.jpony.UI.UserInterfaceManager.resize(UserInterfaceManager.java:103)
	at myGame.Game.loadHud(Game.java:157)
	at myGame.Game.initialize(Game.java:140)
	at myGame.Game.<init>(Game.java:81)
	at myGame.LoadGame.update(LoadGame.java:50)
	at com.jme3.app.state.AppStateManager.update(AppStateManager.java:287)
	at com.jme3.app.SimpleApplication.update(SimpleApplication.java:236)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:151)
	at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:193)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:232)
	at java.lang.Thread.run(Thread.java:745)

It is important to note that is crashing on texture load and it doesn’t always crash in the same spot. The terrain textures seem to be another reason for the crash but I’ll come back to the terrain in a bit.

When I first got the direct buffer memory error it was after modifying my scene. I added one sphere in my scene , ran it , then it crashed. I tried deleting the sphere then running the application but I got the same memory error.

I loaded up my last good scene save then ran the application and it worked fine. I tried adding another sphere and I got the same error. The same as last time removing the sphere did not fix the problem.

I noticed the terrain texture where causing the error so I removed the terrain from the file then ran the app and it worked fine.

My next step I decided to run a memory test on both files the original and the file without the terrain here are my results.

with terrain

initial launch = 35 - 40 mb

title screen = 350 - 450 mb

game = 800 - 1000 mb

with out terrain

initial launch = 35 - 40 mb

title screen = 350 - 450 mb

game = 500 - 600 mb

What is very noticeable is that my title screen has a 400mb foot print. The title screen consist of one low poly model , one low poly animation and one very simple terrain 32x8. The total size of all the models and textures in my project come to about 150mb. A scene with only 3 objects shouldn’t be running with a memory foot print of 400+mb.

The second most noticeable thing is the about 400mb drop in memory usage that comes from removing the terrain.

My terrain uses 5 textures with a 2048x2048 size. They are in tga format and the actual file size around 2mb. I also have a 36mb tga file that is a texture atlas for all of my models. However the atlas has yet to cause a crash. My best guess is this has something to do with the textures.

I tried running the argument -Xmx128m and gradually increasing the size. Anything 1024 or above was crashing the application on launch.

Finally I did one last test.

I ran the working file several times and let it run about 30 minutes each. I noticed after about 10 - 15 minutes into the runt he memory would drop down to around 150 - 250 mb which is a much more reasonable level for the file size.

My biggest question is what could be causing the application to take up so much memory after loading a simple file ?

My second question is does anyone have any suggestions for helping with the direct buffer memory error.

Did you try standing on one foot? Both of these things will affect direct memory size about the same. (read: not at all)

You need to use the direct memory setting to increase the direct memory size. I’ll let you google that (or do a forum search) as t here is likely to be other useful information you will want to know.

I have trouble with this one because I thought targa was uncompressed… and 2048x2048 is already 4 million pixels. If that’s a standard RGB type of image then it’s likely taking up 16 meg of memory. 16 * 5 = 80 meg of textures.

You definitely have a lot of stuff that will be filling up direct memory. I could be that increasing it to 1024 meg is enough for now. Be careful not to overset your max memory or you cause problems for your direct memory (see forum searches recommended above).

I already tried increasing the direct memory to 2048 , which is the default for the sdk , and above. The result is the same. However , I’m not sure if I’m doing it right. I was just putting it in the command arguments line in the project run options.

I did some additional testing and found the issue to be somewhere in the spatial loading process.

I created a new scene. Gave it the default terrain then added in 7 cubes.

I ran the scene. The initial loading memory was about 50mb the within seconds shot down to about 35mb.

I added in a new material with the 36mb tga atlas file and set it to a cube.

I ran the scene. The initial loading memory sky rocketed to about 250 - 300mb. It took about 10 seconds and it went back down to 40 - 50 mb.

I added the same material to multiple cubes then ran the scene. The same initial loading memory but it took about 1 minute for memory to go back down to normal levels. Each time I added the material to an additional cube the memory took longer to recover.

I the set each cube to a different material/texture and ran the project after I set each new material.

The initial loading memory cost increased exponentially with each texture.

initial loading memory

Terrain with cubes - 50mb

terrain with 1 texture cube(the big tga file) - 250mb

terrain with 2 texture cube - 300mb

terrain with 3 texture cube - 370mb

terrain with 4 texture cube - 390mb

terrain with 5 texture cube - 420mb

etc. you get the point.

The other textures where png/tga with 512x512 dimensions.

Each time I added a cube texture the initial load cost went up and the time it took the collector to recover went up exponentially.

I went back to my original scene which gave me the memory error and removed all of the files that used the 36mb tga file and the initial load memory went down by about 550mb.

I had 16 objects times 36 which is 576.

Correct me if I’m wrong but I thought the asset manager loaded only a single copy of a texture if multiple models share the same texture it just uses the original. It seems like the texture is being loaded in it’s entirety for each model in the scene then later being dumped from memory.

I don’t know if that is expected behavior but it seems a little odd to me. Perhaps you can enlighten me on textures , loading spatials and memory usage.

P.S. Loading the scene in the SDK causes the same memory issue. The SDK memory will shoot up by about 500 - 600mb then go back down after 10 minutes or so.

P.S.S even if I increase the direct memory I still need to figure out why the initial loading cost are so high.

P.S.S. I’m using 3.1-beta1-b002-SNAPSHOT

Well, if you changed it and got no different results then you didn’t do it right. 2048 is probably too high anyway.

There is a memory utils class that can tell you what the direct memory is at runtime. That’s going to be a more reliable way to know if you’ve really set it higher and also a more reliable way to see what’s going on with memory than looking at your task memory (which is I assume what you’re doing given the wild fluctuations.)

But anyway now that we are playing the “try this” “Oh, I already tried that” game… I will let someone else play as I have other things to do.

You are right that the second time loading the same texture should basically be free as it’s cached. Stepping in the debugger should confirm this.

Aye , I got it working with. -Xmx128m -Xms24m -XX:MaxDirectMemorySize=512m

After running some profiling and just getting lucky I realized the initial load memory is only held onto in windowed mode. If I switch between applications it gets dumped almost immediately. If I run in full screen mode the memory used to load is dumped immediately as well.

Something in windowed mode is causing the garbage collector to hang onto the initiating objects.