A strange OutOfMemory error when loading textures

I am trying to load a bunch of high-resolution (1920x1080) textures. Yes, I know that they are big and that loading big textures is a bad idea, but that’s not the point. What is strange is that specifying different heap sizes does not influence the amount of successfully loaded textures as expected.



The following characteristic takes place:



[java]

-Xmx textures loaded


default 26
512M 57
1024M 42
1536M 4
[/java]

The number of loaded textures varies by one or two on every sequential run with a particular memory setting. The dynamics of the dependency is quite opposite to what I have imagined it to be. And the visualvm tool does not show even that - it just ignores the size of loaded textures when hooked to the running project.

How much does a loaded texture take? I assume it is something like 1920 * 1080 * 4 / (1024 * 1024) = 7.91 MB.... So I can believe that 57 such textures fill up the 512 Mbs, but what about 1024 and above?

How can this dynamics be explained? Let alone the HD textures, but Is it possible to acheive a fine control of the memory consumption while loading textures?

The stack trace:

[java]
Apr 24, 2012 8:00:26 PM com.jme3.app.Application handleError
SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,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 com.jme3.util.BufferUtils.createByteBuffer(BufferUtils.java:908)
at com.jme3.texture.plugins.AWTLoader.load(AWTLoader.java:113)
at com.jme3.texture.plugins.AWTLoader.load(AWTLoader.java:191)
at com.jme3.texture.plugins.AWTLoader.load(AWTLoader.java:201)
at com.jme3.asset.DesktopAssetManager.loadAsset(DesktopAssetManager.java:273)
at com.jme3.asset.DesktopAssetManager.loadTexture(DesktopAssetManager.java:325)
at com.jme3.asset.DesktopAssetManager.loadTexture(DesktopAssetManager.java:344)
at com.jme3.asset.DesktopAssetManager.loadTexture(DesktopAssetManager.java:356)
at org.isborsk.loaders.ImageLoader$.loadImage(ImageLoader.scala:39)
at org.isborsk.loaders.ImageLoader$$anonfun$loadSequence$1.apply(ImageLoader.scala:51)
at org.isborsk.loaders.ImageLoader$$anonfun$loadSequence$1.apply(ImageLoader.scala:46)
at scala.collection.immutable.Range.foreach(Range.scala:75)
at org.isborsk.loaders.ImageLoader$.loadSequence(ImageLoader.scala:46)
at org.isborsk.states.map.MapInterfaceTemplate.initYearGroupA(MapInterfaceTemplate.scala:170)
at org.isborsk.states.map.MapInterfaceA$.<init>(MapInterfaceA.scala:17)
at org.isborsk.states.map.MapInterfaceA$.<clinit>(MapInterfaceA.scala)
at org.isborsk.states.map.MapInterfaceTemplate.miA(MapInterfaceTemplate.scala:286)
at org.isborsk.states.map.MapInterfaceTemplate.initCenturyButtons(MapInterfaceTemplate.scala:340)
at org.isborsk.states.map.MapInterface0$.<init>(MapInterface0.scala:5)
at org.isborsk.states.map.MapInterface0$.<clinit>(MapInterface0.scala)
at org.isborsk.main.TestAppButton$.isborskA(TestAppButton.scala:84)
at org.isborsk.main.TestAppButton$.simpleInit(TestAppButton.scala:39)
at org.jmetouch.app.TouchApp.simpleInitApp(TouchApp.scala:30)
at com.jme3.app.SimpleApplication.initialize(SimpleApplication.java:231)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.initInThread(LwjglAbstractDisplay.java:129)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:205)
at java.lang.Thread.run(Unknown Source)[/java]

Its direct memory, nothing to do with the java heap. Issue with them is they do not trigger the GC but only get cleared when a GC happens. Solution is to have a fairly large direct memory size and a relatively small java heap size so the GC is triggered more often.

2 Likes

Add this to your JVM settings for the project:

-XX:MaxDirectMemorySize=1024m



And then send me many fancy gifts. :wink:

3 Likes

Thank you! I now understand the problem. This is very good. I have tried increasing the size as pspeed have mentioned and increased the number of loaded pictures but… this is not a liveable application design, so I just wanted to understand the situation I got into and make the experiment… I will choose a different tecnique to complete the task!

1 Like