OutOfMemoryError treshold for GameStates?

Hi,



after having started my StandardGame I initialize some MenuStates(also GameStates) within the same main() method and attach it to the GameStateManager. So far everything works.



Now… the problem arises by clicking on the button "start singleplayer" which starts initializing the the main GameState (the actually game).–> OutOfMemoryError stops the whole application. The initialization is not finished.



INFO: Child (TerrainPage4) attached to this node (Terrain)
20.09.2008 12:50:03 class com.jmex.awt.swingui.JMEDesktop onButton(swingButton, pressed, x, y)
SCHWERWIEGEND: Exception
java.lang.reflect.InvocationTargetException
   at java.awt.EventQueue.invokeAndWait(EventQueue.java:997)
   at javax.swing.SwingUtilities.invokeAndWait(SwingUtilities.java:1323)
   at com.jmex.awt.swingui.JMEDesktop.onButton(JMEDesktop.java:451)
   at com.jmex.awt.swingui.JMEDesktop$ButtonAction.performAction(JMEDesktop.java:1173)
   at com.jme.input.ActionTrigger.performAction(ActionTrigger.java:259)
   at com.jme.input.InputHandler.processTriggers(InputHandler.java:420)
   at com.jme.input.InputHandler.update(InputHandler.java:405)
   at com.jme.input.InputHandler.updateAttachedHandlers(InputHandler.java:434)
   at com.jme.input.InputHandler.update(InputHandler.java:406)
   at mce.gui.states.outgame.BaseMenuState.update(BaseMenuState.java:84)
   at com.jmex.game.state.GameStateNode.update(GameStateNode.java:71)
   at com.jmex.game.StandardGame.update(StandardGame.java:323)
   at com.jmex.game.StandardGame.run(StandardGame.java:198)
   at java.lang.Thread.run(Thread.java:619)
Caused by: java.lang.OutOfMemoryError: Direct buffer memory
   at java.nio.Bits.reserveMemory(Bits.java:633)
   at java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:95)
   at java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:288)
   at com.jme.util.geom.BufferUtils.createByteBuffer(BufferUtils.java:814)
   at com.jme.util.TextureManager.loadImage(TextureManager.java:616)
   at com.jme.util.TextureManager.loadImage(TextureManager.java:477)
   at com.jme.util.TextureManager.loadImage(TextureManager.java:452)
   at com.jme.util.TextureManager.loadImage(TextureManager.java:428)
   at com.jme.util.TextureManager.loadTexture(TextureManager.java:331)
   at com.jme.util.TextureManager.loadTexture(TextureManager.java:292)
   at com.jme.util.TextureManager.loadTexture(TextureManager.java:242)
   at mce.game.data.terrain.MCE_Terrain.<init>(MCE_Terrain.java:103)
   at mce.game.states.TestState.buildTerrain(TestState.java:273)
   at mce.game.states.TestState.<init>(TestState.java:166)
   at mce.gui.states.outgame.MenuState_Einzelrennen$1$1.actionPerformed(MenuState_Einzelrennen.java:65)
   at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
   at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
   at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
   at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
   at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
   at java.awt.Component.processMouseEvent(Component.java:6041)
   at javax.swing.JComponent.processMouseEvent(JComponent.java:3265)
   at java.awt.Component.processEvent(Component.java:5806)
   at java.awt.Container.processEvent(Container.java:2058)
   at java.awt.Component.dispatchEventImpl(Component.java:4413)
   at java.awt.Container.dispatchEventImpl(Container.java:2116)
   at java.awt.Component.dispatchEvent(Component.java:4243)
   at com.jmex.awt.swingui.JMEDesktop.dispatchEvent(JMEDesktop.java:670)
   at com.jmex.awt.swingui.JMEDesktop.sendAWTMouseEvent(JMEDesktop.java:845)
   at com.jmex.awt.swingui.JMEDesktop.access$11(JMEDesktop.java:777)
   at com.jmex.awt.swingui.JMEDesktop$7.run(JMEDesktop.java:453)
   at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:199)
   at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
   at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
   at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
   at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
   at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
   at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
   at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)



Notice: I sucessfully tested to start the main GameState by reducing the number of MenuStates. But that's not the thing the problem is supposed to depend on. But it apparently does :?


I want to ask what causes this OutOfMemoryError and what can be done do avoid this.

I assume this problem is related to the implementation of the GameStateManager. It uses an ArrayList<G extends GameState> which is not initialized with a given capacity. I guess the ArrayList is not able to pick up a another big GameState.

Another assumption is that it a problem of the OpenGL thread which has not enough memory for the stack or the main thread where the main GameState is created dynamically.

The problem is very important as we would like to create more GameStates but now the treshold is reached at about 5 states :|

I hope sombody has faced the same problem and knows the problem itself and has some solution for that. :)

I hit this same error when I tried to initialize more than a handful of states.  The solution was to increase the amount of memory allocated to the JVM.

the problem is not the number of gamestates, but the direct memory you use in the GameStates constructor.



you can increase the direct memory size with a jvm option:

  -XX:MaxDirectMemorySize=<value> 



see also:

http://www.jmonkeyengine.com/wiki/doku.php?id=links

Thanks! I havn't fixed the problem :cry:



I don't know how I can set the MaxDirectMemorySize in Eclipse :oops:



Is there another way to ensure that the memory allocation has enough space? I think of creating a new process which has all the space for his threads. But that's new for me.



How can a game be deployed after it is finished? I thought of a simple JAR. But Now: Will a java-noob be able to play the game with an current version of jre wihtout having to tune the jvm?



I dont't like solution for that if it's also a problem to play the game after developement.



Idea: is it possible to create a new Thread for every new GameState to be loaded, will that touch my problem?

In Eclipse:

  1. Right-click on your project and select 'Properties'
  2. Select 'Run/Debug Settings' in the left pane
  3. Select the appropriate Launch Configuration on the right and press 'Edit'
  4. Select the 'Arguments' tab
  5. Type the following in the "VM Arguments" pane: -Xmx1G
  6. Press 'OK' to close the Launch Configuration window
  7. Press 'OK' to close the project properties window



    If you don't like this solution, I'm not aware of another besides to reduce the amount of memory your program needs.  The easiest way I know of for an end-user to do the same thing is to provide a bat script that calls the jar and start class with the proper VM arguments.  Then the user just needs to run the batch file to start the program.  There may be easier ways to do it.