[SOLVED] OutOfMemoryError When Running JME App With ProcessBuilder

Hi Guys,
I guess this is more a Java question than a JME question.
I’m getting an OutOfMemoryError while loading the models to my game:

Jun 11, 2020 7:55:45 PM com.jme3.app.LegacyApplication handleError
SEVERE: Uncaught exception thrown in Thread[jME3 Main,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.ReflectionAllocator.allocate(ReflectionAllocator.java:178)
	at com.jme3.util.BufferUtils.createByteBuffer(BufferUtils.java:989)
	at com.jme3.texture.plugins.AWTLoader.load(AWTLoader.java:121)
	at com.jme3.texture.plugins.AWTLoader.load(AWTLoader.java:183)
	at com.jme3.texture.plugins.AWTLoader.load(AWTLoader.java:192)
	at com.jme3.asset.DesktopAssetManager.loadLocatedAsset(DesktopAssetManager.java:260)
	at com.jme3.asset.DesktopAssetManager.loadAsset(DesktopAssetManager.java:374)
	at com.jme3.asset.DesktopAssetManager.loadTexture(DesktopAssetManager.java:391)
	at com.jme3.scene.plugins.gltf.GltfLoader.readImage(GltfLoader.java:737)
	at com.jme3.scene.plugins.gltf.GltfLoader.readTexture(GltfLoader.java:695)
	at com.jme3.scene.plugins.gltf.GltfLoader.readTexture(GltfLoader.java:679)
	at com.jme3.scene.plugins.gltf.GltfLoader.readMaterial(GltfLoader.java:621)
	at com.jme3.scene.plugins.gltf.GltfLoader.readMeshPrimitives(GltfLoader.java:439)
	at com.jme3.scene.plugins.gltf.GltfLoader.readNode(GltfLoader.java:217)
	at com.jme3.scene.plugins.gltf.GltfLoader.readChild(GltfLoader.java:268)
	at com.jme3.scene.plugins.gltf.GltfLoader.readChild(GltfLoader.java:276)
	at com.jme3.scene.plugins.gltf.GltfLoader.readScenes(GltfLoader.java:183)
	at com.jme3.scene.plugins.gltf.GltfLoader.loadFromStream(GltfLoader.java:127)
	at com.jme3.scene.plugins.gltf.GltfLoader.load(GltfLoader.java:78)
	at com.jme3.asset.DesktopAssetManager.loadLocatedAsset(DesktopAssetManager.java:260)
	at com.jme3.asset.DesktopAssetManager.loadAsset(DesktopAssetManager.java:374)
	at com.jme3.asset.DesktopAssetManager.loadModel(DesktopAssetManager.java:417)
	at com.scenemaxeng.projector.SceneMaxApp.loadModel(SceneMaxApp.java:1321)
	at com.scenemaxeng.projector.SceneMaxApp.instantiateVariable(SceneMaxApp.java:1006)
	at com.scenemaxeng.projector.InstantiateGraphicEntityController.run(InstantiateGraphicEntityController.java:22)
	at com.scenemaxeng.projector.CompositeController.run(CompositeController.java:69)
	at com.scenemaxeng.projector.SceneMaxApp.simpleUpdate(SceneMaxApp.java:2326)
	at com.jme3.app.SimpleApplication.update(SimpleApplication.java:258)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:153)
	at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:193)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:234)
	at java.lang.Thread.run(Unknown Source)

java.lang.OutOfMemoryError

I understand that it is due to lack of DirectMemory so when I run the program from the command line with the -XX:MaxDirectMemorySize=1024m switch it works fine:

java -XX:MaxDirectMemorySize=1024m -jar launcher1.4.5.jar

But when I run the same program using ProcessBuilder I’m getting the OutOfMemoryError which I have shown in the above stack trace.
Any ideas why ProcessBuilder doesn’t pass on the -XX:MaxDirectMemorySize=1024m switch?

Thanks!

Can you show us the code relating to how you build the process?

Sure!

command.add("java");
            command.add("-XX:MaxDirectMemorySize=1024m");
            command.add("-Xmx1024m");
            command.add("-jar");
            command.add(launcherName);

            ProcessBuilder processBuilder = new ProcessBuilder();
            processBuilder.command(command);
            File log = new File("log");
            if(log.exists()) {
                log.delete();
            }
            processBuilder.redirectErrorStream(true);
            processBuilder.redirectOutput(ProcessBuilder.Redirect.appendTo(log));
            Process process = processBuilder.start();

            StreamGobbler sg = new StreamGobbler(process.getInputStream(),System.out::println);
            Executors.newSingleThreadExecutor().submit(sg);
            int exitCode = process.waitFor();
            System.out.printf("Program ended with exitCode %d", exitCode);

meanwhile after wasting too much time on such a simple task, I found a workaround - I made the ProcessBuilder to run a bat file containing the java -jar … command and this made it to work as expected.

OK, I found the root cause of the problem - It was my Java version which is 32 bit. I checked using:

java -XshowSettings:properties -version

Uninstalled it and installed the 64 bit version and now everything works as expected.

3 Likes