How much memory is too much?

Let me give you some background of my scenario. I am creating a game to turn into FBLA, a student organization. They will judge my game and give me a score on it. So far, I’ve been on my own besides the help of the people here on this forum. I try to ask my advisor the simplest of questions about formatting the game properly, what kind of hardware it will be run, etc., but he has no idea. I’m at a loss of what to expect.

My question I have is, how much memory is too much? To me, it’s obvious that it depends on the computer. I get that. BUT WHAT IF I DON’T KNOW WHAT TYPE OF COMPUTER IT WILL BE RUN ON? Naturally, the best bet is to use the industry standards. But I have no idea what that is. If you took an average computer in an office, and played a game on it, how much memory would be too much?

My game’s memory usage varies. It can exceed 1000MB at times, which scares me. Don’t tell me I’m not removing references, I know I am. I also know to call clearcache() on the assetManager. I’ve been doing that. Heck, I even tried doing that every frame. On average, 900MB is generally the peak. The garbage collector does cut in eventually, but only after it nearly gives me a heart attack with those high peak memory usages.

There also lies the question of if I even understand how the garbage collector works. On computers with less memory, does it “garbage collect” more often? I played my game on a computer with less memory than what I have and it had an out of memory error, so I don’t think that that’s necessarily true. Also, is there a way to disable the Assetmanager’s caching ability? I’d rather have a game that has slow loading models than one that does not work. Maybe it’s possible my game is keeping references elsewhere. I shall look in my code.

I’m sorry if I appear frustrated or rude. This is a very stressful period of time for me, with the impending doom of 100+ hours of work (from a highschool student mind you) going down the drain. Answers to the questions how much is too much, how the garbage collector works, and how to disable Assetmanager’s caching ability are what I’m looking for I guess. As this post waits I am going to review the rest of my code.

Alright, I won’t rule out it’s my code. Here are the two classes. The attached set of rooms is told to execute removeSelf() and the new
batch of rooms is told to exectute attachSelf(). They are also told to updateCenterObject() when a specific action in gameplay occurs. Doors are first called to do attachSelf(), and then each new floor they are told to reset(). They are also told to unlock() and open() during gameplay. These are the only places I load models so the memory issue must be in here, if there even is one. It’s entirely possible that I’m freaking out about nothing, that the garbage collector will begin to do it’s job when the judges are testing.

[java]
public class Room
{
protected Main app;

private String event;
private String scenario;
private String question;
private String solution;
private String correction;

protected int x;
protected int z;

private boolean scene;
private Spatial roomScene;
private RigidBodyControl roomControl;
private CollisionShape sceneShape;

private Spatial centerObject;
private RigidBodyControl centerObjectControl;   
private CollisionShape centerObjectShape;
protected static int numberOfRooms = 0;
protected String roomID;
private boolean updateCenter;

public Room(String event, String scenario, String question, String solution, String correction, Boolean scene, Boolean updateCenter, Main app)
{
    this.app = app;
    
    this.event = event;
    this.scenario = scenario;
    this.question = question;
    this.solution = solution;
    this.correction = correction;
    this.scene = scene;
    this.updateCenter = updateCenter;

    x = 0;
    z = 0;
    
    numberOfRooms++;
    roomID = "Room" + numberOfRooms + "!";
}

public Room(Main app)
{      
    this.app = app;
    numberOfRooms++;
    roomID = "BonusRoom" + numberOfRooms + "!";   
}

public void attachSelf(int givenX, int givenZ)
{
    x = givenX;
    z = givenZ;
      
    if ( scene )
    {
        roomScene = app.getAssetManager().loadModel("Models/Rooms/" + event + " Scene/" + event + " Scene.j3o");
        roomScene.setLocalScale(1.35f);
        roomScene.setLocalTranslation(22 * x, 2, -22 * z);
        roomScene.setName("Scenery!");
        sceneShape = CollisionShapeFactory.createMeshShape((Node) roomScene);
        roomControl = new RigidBodyControl(sceneShape, 0);
        roomScene.addControl(roomControl);     
        app.getBulletAppState().getPhysicsSpace().add(roomControl);
        app.getCollidables().attachChild(roomScene);
    }
        centerObject = app.getAssetManager().loadModel("Models/Rooms/" + event + "/" + event + ".j3o");
        centerObject.setLocalScale(1.35f);
        centerObject.setName(roomID);
        centerObject.setLocalTranslation(22 * x, 2, -22 * z);
        centerObjectShape = CollisionShapeFactory.createMeshShape((Node) centerObject);
        centerObjectControl = new RigidBodyControl(centerObjectShape, 0);
        centerObject.addControl(centerObjectControl);
        app.getBulletAppState().getPhysicsSpace().add(centerObjectControl);
        app.getCollidables().attachChild(centerObject);  
}

public void updateCenterObject()
{
    if (updateCenter)
    {
        centerObject.removeControl(centerObjectControl);
        app.getBulletAppState().getPhysicsSpace().remove(centerObjectControl);
        app.getCollidables().detachChild(centerObject);

        centerObject = app.getAssetManager().loadModel("Models/Rooms/" + event + " Complete/" + event + " Complete.j3o");
        centerObject.setLocalScale(1.35f);
        centerObject.setName(roomID);
        centerObject.setLocalTranslation(22 * x, 2, -22 * z);
        centerObjectShape = CollisionShapeFactory.createMeshShape((Node) centerObject);
        centerObjectControl = new RigidBodyControl(centerObjectShape, 0);
        centerObject.addControl(centerObjectControl);
        app.getBulletAppState().getPhysicsSpace().add(centerObjectControl);
        app.getCollidables().attachChild(centerObject);
    }
    
        ( (DesktopAssetManager) app.getAssetManager()).clearCache();
}

public void removeSelf()
{
    if ( roomScene != null )
    {
        roomScene.removeControl(roomControl);
        app.getBulletAppState().getPhysicsSpace().remove(roomControl);
        app.getCollidables().detachChild(roomScene);
        roomScene = null;          
        roomControl = null;
        sceneShape = null;
    }
    
        centerObject.removeControl(centerObjectControl);
        app.getBulletAppState().getPhysicsSpace().remove(centerObjectControl);
        app.getCollidables().detachChild(centerObject);
        centerObject = null;
        centerObjectControl = null;
        centerObjectShape = null;

    event = null;
    scenario = null;
    question = null;
    solution = null;
    correction = null;
    roomID = null;
}

}
[/java]

[java]
public class Door
{
private Main app;

private Spatial doorModel;
private RigidBodyControl rigidDoor;
private CollisionShape doorShape;

private int x;
private int z;
private boolean orientation; /* true = horizontal, false = vertical */
private static int numberOfDoors = 0;

private boolean unlocked;
private boolean opened;

       
public Door(Main app, int x, int z, boolean orientation)
{
    /*  The class constructor; initializes member variables */
    this.app = app;
    this.x = x;
    this.z = z;
    this.orientation = orientation;
    numberOfDoors++;
    unlocked = false;
    opened = false;    
}

public void createDoor()
{
    this.doorModel = app.getAssetManager().loadModel("Models/Door/Door.j3o");
    doorModel.setName("Door" + numberOfDoors + "!");
    doorModel.setLocalScale(2f);
    doorModel.setLocalTranslation(x, 2f, z); 
    if (!orientation)
    {
        doorModel.rotate(0f, -1 * FastMath.HALF_PI , 0f);
    }
    
    doorShape = CollisionShapeFactory.createMeshShape((Node) doorModel); 
    rigidDoor = new RigidBodyControl(doorShape, 0);
    doorModel.addControl(rigidDoor);              
    app.getBulletAppState().getPhysicsSpace().add(rigidDoor);
    app.getCollidables().attachChild(doorModel);  
}

public void unlock()
{
    unlocked = true; 
}

public void open()
{
    if (unlocked && !opened)
    {
        app.getAudioManager().playAudioNode("door");       
        doorModel.removeControl(rigidDoor);
        app.getBulletAppState().getPhysicsSpace().remove(rigidDoor);
        doorModel.rotate(0f, FastMath.PI, 0f); 
        opened = true;
    }                   
}

public void reset(Main app)
{
    unlocked = false;
    opened = false;

    app.getCollidables().detachChild(doorModel);
    doorModel.setLocalRotation(Quaternion.ZERO);
    
    if (!orientation)
    {    
        Quaternion doorRotate = new Quaternion();
        doorModel.setLocalRotation(doorRotate.fromAngleAxis(-1f * FastMath.HALF_PI, Vector3f.UNIT_Y));
    }
    
    doorModel.addControl(rigidDoor);             
    app.getBulletAppState().getPhysicsSpace().add(rigidDoor);
    app.getCollidables().attachChild(doorModel);
}

}
[/java]

there really is no industry standard.

all relatively recent computers have atleast 2 gigs of ram, 4 is quite common, gaming or high end computers will have more than 4 gigs.

atleast 1 gig of ram is probably going to be used up in general operating system stuff or just other programs running, the rest is more or less yours to do as you please for the most part. Use as much as you need and leave enough to do whatever you need to do in your game.

just to note though, if youre only on the beginnings of your game and it doesnt have any intensive content like very large textures or highly detailed models then its quite untypical to be using a whole gig of ram…

are you sure that the 1000 megabytes youre seeing isnt just how many are being reserved for your game by java?

in your program if you do Runtime.getRuntime().totalMemory() that shows how much memory youre actually using, getRuintime().maxMemory() is how much java has allocated for your program.

Alright, thank you for the response despite my unprofessionalism. I’ll go ahead and see what those methods return. The memory numbers I was going off of were from the task manager, so yeah it could be just the total memory. If that’s the case is there anything I can do about that? Or is that a problem at all?

Also, can system administrators put memory caps on computers? I tested out my game on the schools computers which are communistically controlled. The memory error I recieved from that could have been related to a memory cap (but honestly I have no idea what I’m talking about).

This begs a final question, is it possible for someone to increase allocated memory to a game? Could I, as the developer, include instructions to do this?

Oh, and you mentioned very large textures. Nearly all of my textures are 1024 by 1024. Is that the issue? Would scaling them down significantly reduce memory?

You’re right about the memory thing. I tried that first method and the highest number I got was 381550592. I take it that’s 381 MB.
Much less than what I thought. So now my only question is about the schools computer. Why did it error? In about 9 hours or so I shall be able to test it again. The error said “out of memory”. Also, models stopped loading on some playtests as well. Any input is cherished.

You could increase the memory/heap-size of your game here is the link to how to do it. 512 by 512 textures will take up less memory than 1024 by 1024. The smaller the image the less memory it will take up. I am not sure about the “Admin memory usage limit” I never heard of that :-? .

And note: increasing heap size won’t give you any more texture or mesh memory. You have to increase the direct memory size. (scroll down a little in that thread)

Well seeing that 4gb is even in the cheapest discounter pc’s (at least here in germany) I would say using up to 1.5GB if fine. (The 1.5 due to windows not being able to address mroe on 32bit machines).

If you know you can use 64bit os, then I would say 3gb is more or less save.
Keep in mind that if you do not explicitly configure memory bounds most jvm try to make guesses, wich can be from great to catastrophic.

@BrianMan said: Naturally, the best bet is to use the industry standards. But I have no idea what that is.

I’m basically going to reiterate what has already been said that there is no “standard” but I can provide an interesting “for instance” case. I’ve worked for the same company for 5 years and have had a variety of machines. Not to add to your stress but it really depends on your role within an industry to dictate what is your standard. My first laptop was a measly DELL D630. I had that for 3 years.

Specs
Proc - 1.8GHz Dual Core (32bit)
Mem - 512MB (Ya. I know. How I was even able to load Word at times blows my mind)
Graphics - Integrated Intel Video Card (I think I threw up a little typing that)

Then I changed roles and forced the issue of a new laptop since I do primarily Java development for a security team (You’d think that’d make me a mad leet coder or something… but it don’t). However I got a “standard development machine” at that point.

Dell E6530
Specs:
Proc: Intel i7 2.60GHz dual quad core (64bit)
Mem: 16GB
Graphics: Nvidia nvs 5200m

So ya. No such thing as a standard. But if I had to ball park at MINIMUM 2GB of mem should be there.

Okay, no industry standard. All these different memory numbers leave me a bit confused. It sounds like the number on the task manager is completely irrelevant. So there are 4 numbers I should be worried about: Runtime.getRuntime().totalMemory(), Runtime.getRuntime().maxMemory(), the heap size, and the direct memory size. I’m under the impression maxMemory = heap size, and totalMemory must always be less than direct memory? I guess what I’m saying is, what am I trying to optimize? What caused the error? I tested it again and I still get an “OutOfMemoryEffor: Direct buffer memory” that pops up.

well than its the direct memory not being large enough.

So, if I infer correctly, I should change it following the instructions of that link. So should it be 450 or so if my game peaks at 380? Or is that a different number. And should I bother changing the heap memory if that’s not the problem? I understand the heap memory is basically an indicator for when the garbage collector needs to do its job. So should my heap memory be less than my direct memory?

Your heap should be so dimensions that it needs runs out, but is low enough to ensure the gc runs from time to time.

Okay, so that mostly makes sense, but I’m not quite sure what dimensions mean/are. Are you saying it should be high enough to run smoothly but low enough to run the garbage collector to keep it under the direct memory that I allocate? And is that 380 Mb correct, is that the number I should go off of?

Java provides no natural way to tell how much direct memory you have. There is a back-door way to get it on Java 1.7+ that is included in JME’s MemoryUtils.

General rule of thumb I use: set max heap to 512 mb and direct memory to 1 gig. Adjust from there as needed.

-Xmx512m -XX:MaxDirectMemorySize=1024m

Okay, I tried doing that and it still didn’t solve my problem. Even when the second level loads my game just errors. I guess I don’t understand the semantics enough to “adjust from there as needed”. How do I know which number is too high or too low?

Anyways, I may have found a roundabout solution. I ran this game as a windows exe and it worked beautifully. That’s where the system administrator stuff that I made up came in to play: the schools computers don’t allow exe to run, so I was testing it with the jar file instead. So, does this memory stuff apply to exes? Am I okay just sending in the exe version, or is that at risk for running out of memory as well? That hasn’t happened to me yet.

Well, that’s important information.

If you run the jar directly then you will need to do it from the command line and you will need to pass the memory options manually.

Hey, cool I’m creating my game for TSA, a very similar student organization.
I currently use about .3-.4 gigs of memory, but I only have 1 texture for everything in the game. I’m betting textures take up most of the memory (just a guess though).
Good luck to you!

Edit:
Mind uploading a video to youtube of your game? I’d like to see what other students are making in these kinds of competitions.

Okay, it looks like my problem is solved in that case. Darn I must sound like a noob.

And I would love to upload a video, but you’d either have to point me in the direction of a screen capturing software or get a crappy real life camera view :slight_smile:

http://hub.jmonkeyengine.org/javadoc/com/jme3/app/state/VideoRecorderAppState.html