(Resolved) Gamebreaking Memory Issues

Hello,

Im seeing some very concerning issues with memory “leaks” in the JMonkey engine. We first started seeing our game take little “jumps” periodically, and weve traced it down to a delay in the frame when the JVM garbage collection occurs. So I went to a bare-bones SimpleApplication and am seeing the same issue. With a framerate of 100, Im seeing garbage collection happen up to every 70ms!!! Im thinking this should definitely not be happening in a simple application, and its causing display issues that make our game look very bad!



In below output, first number is free memory, 2nd is size of memory change, 3rd is time since last memory change.



Here we see some new memory being added every 10ms:



UsedMem 21617.836 memdiff 985.25 timediff 10

UsedMem 22603.008 memdiff 985.1719 timediff 9

UsedMem 23588.258 memdiff 985.25 timediff 9

UsedMem 24573.508 memdiff 985.25 timediff 10

UsedMem 25558.758 memdiff 985.25 timediff 10

UsedMem 26543.93 memdiff 985.1719 timediff 10



In the code segment below, comment/uncomment the “if” statements below “LOOK HERE” to see how often we garbage collect:



UsedMem 1918.3828 memdiff -8324.211 timediff 73

UsedMem 1886.3828 memdiff -8436.211 timediff 74

UsedMem 1854.3047 memdiff -8436.289 timediff 74

UsedMem 1854.2422 memdiff -8404.352 timediff 72

UsedMem 1886.3828 memdiff -8372.211 timediff 74





Also note, if you comment out the call to printCheckMem and uncomment the freeMemory print, youll see it drastically changing constantly.



Thanks in advance!



(Note: Im current to 3/6/2011 nightly build)



[java]package memtest;



import com.jme3.app.SimpleApplication;

import com.jme3.material.Material;

import com.jme3.math.Vector3f;

import com.jme3.scene.Geometry;

import com.jme3.scene.shape.Box;

import com.jme3.math.ColorRGBA;

import com.jme3.system.AppSettings;

import com.jme3.system.JmeContext;

import java.util.logging.Level;

import java.util.logging.Logger;



/** Sample 1 - how to get started with the most simple JME 3 application.

  • Display a blue 3D cube and view from all sides by
  • moving the mouse and pressing the WASD keys. */

    public class Main extends SimpleApplication {



    public static void main(String[] args){

    Main app = new Main();



    Logger.getLogger("com.jme3").setLevel(Level.WARNING);

    Logger.getLogger("de.lessvoid.nifty").setLevel(Level.OFF);



    AppSettings mAppSettings = new AppSettings(true);

    mAppSettings.setFrameRate(100);

    app.start(JmeContext.Type.Display);

    }



    @Override

    public void simpleInitApp() {

    }



    @Override

    public void simpleUpdate(float tpf) {

    printCheckMem("UsedMem");

    // System.out.println(Runtime.getRuntime()

    // .freeMemory());

    }





    private static float oldUsedMem = 0;

    private static float newUsedMem = 0;

    private static float kb = 1024;

    private static long oldSysTime = System.currentTimeMillis();

    private static long newSysTime = 0;



    public void printCheckMem(String label) {

    newUsedMem = (Runtime.getRuntime().totalMemory() - Runtime.getRuntime()

    .freeMemory()) / kb;



    ///// LOOK HERE

    if (Math.abs(newUsedMem - oldUsedMem) > 0)

    // if ((newUsedMem - oldUsedMem) < 0)

    {

    newSysTime = System.currentTimeMillis();

    System.out.println(label + " " + newUsedMem + " memdiff "
  • (newUsedMem - oldUsedMem) + " timediff " + (newSysTime - oldSysTime));

    oldSysTime = newSysTime;

    }

    oldUsedMem = newUsedMem;

    }

    }[/java]

Just curious… I assume the statistics display is showing when running the simple app by itself. What does the memory look like if you turn that off?



Also, what version of JME are you running? Base alpha 3 or a recent nightly?


hoggle said:
So I went to a bare-bones SimpleApplication and am seeing the same issue. With a framerate of 100, Im seeing garbage collection happen up to every 70ms!!!


Also note here that the amount of change may be alarming but the frequency might not be. A JME apps with nothing in it would happily spin at 2000 frames per second on my box... so limiting it to 100 FPS would leave lots of idle cycles. Idle cycles could cause the garbage collector to run more often than it might otherwise.

Are you also turning on GC logging for the application? The incremental sweeps are nothing... it's the large full GC that should concern you because that really means dropped frames.

Mythruna chews through direct memory like crazy and takes a pretty big full GC hit every so often. (Sometimes up to 100 ms long, entire app frozen.) I've currently taken it as the price I pay for generating so much geometry on the fly but I'll be interested to see if there are ways to minimize this. Sometimes having more control over Java's GC would be nice but in the end there is little that can be done, I guess.

Note: it is theoretically possible that the stats display chews through some amount of direct memory as it potentially regenerates its geometry. I've looked at the code and it tries to reuse what it already allocated but it's complicated enough that I can't be sure. That's why I asked about whether it was up or not. It definitely chews through some heap... though even your printlns will do that.

Wow! Yes, it was the statistics. There is still some object creation now and then happening, but nowhere “near” the amount I was seeing before. I wouldnt have thought that would do it.



Thanks for the response

For anyone looking at this thread, if youre having memory issues, try removing the statistics (guiNode.detachAllChildren()) to fix what Ive described in the OP

Can you follow up with the JME3 version that you are using? Maybe this has been fixed… maybe recently made worse… no way of telling at this point. :slight_smile:

Im current to 3/6/2011 nightly build, JME 1.3





Im seeing some more memory issues outside of my managed code in my actual project, just not nearly to this scope. I’ll report back what I find

For anyone looking at this thread, if youre having memory issues, try removing the statistics (guiNode.detachAllChildren()) to fix what Ive described in the OP


Btw, if you prefer a more surgical method, you can use:

[java]guiNode.detachChildNamed("Statistics View");[/java]

And also note: when the BitmapText fixes from last night hit the nightlies… it’s probably worth retesting since that should fix the thrashing.



…specific to stats, that is.