out of memory...again

Started by dutch_delight, May 10, 2012, 02:46:09 PM

Previous topic - Next topic

dutch_delight

I have a problem when resetting my game.

I have a couple of levels which are populated from a pool of objects using an xml file. everything works fine untill i restart a level or pick a new level. I think my models remain in memory but i do clear them.

this is how it works:



I'm declaring an array and a world so i can easily access my objects:
private List<Object3D> worldObjectsArray = new ArrayList<Object3D>();
private List<Integer> worldObjectsArrayType = new ArrayList<Integer>();//identifies the object type
private Object3D worldEnvironment = null


Then i load my world when a level is selected from the frontend:
worldEnvironment = Loader.loadSerializedObject(res.openRawResource(R.raw.levelA));
worldEnvironment.setTexture("levelAtexture");
worldEnvironment.getMesh().compress();
worldEnvironment.forceGeometryIndices(true);
worldEnvironment.build();
worldEnvironment.strip();
world.addObject(worldEnvironment);
worldEnvironment.addCollisionListener(this);



then I process an xml file and get the object type from it: (exluded the loop from example)
node = getxmlelement;//this is an xml element loaded from a loop

if (node == "buildingA") {
tempobject = new Object3D((Loader.loadSerializedObject(res.openRawResource(R.raw.buildinga))), true);
tempobject.setTexture("texturepage1");
objectType = 1;
}

if (node == "carA") {
tempobject = new Object3D((Loader.loadSerializedObject(res.openRawResource(R.raw.cara))), true);
tempobject.setTexture("vehicles");
objectType = 2;
}


tempobject.strip();
tempobject.build();
worldObjectsArray.add(tempObject);
worldObjectsArrayType.add(objectType);
world.addobject(tempObject)
tempobject = null;



which all works fine, my world is populated and I can access all objects no problem.
All transforms and data comes through from the xml fine.

but when I reset my game or game over I call reset:

if (worldObjectsArray.size() > 0) {

for (int i=worldObjectsArray.size()-1;i>=0;i--) {
if (worldObjectsArray.get(i) != null) {
world.removeObject(worldObjectsArray.get(i));
worldObjectsArray.set(i,null);//probably overkill
}
}
}
worldObjectsArray.clear();
worldObjectsArrayType.clear();



and reset the world:
world.removeObject(worldEnvironment);
worldEnvironment=null;


after this, my world.size() is zero, the array is cleared and i should have some more free ram but no.
the memory that was filled when loading the level is not cleared and it looks like the model references are kept in ram. Because when i reload the level, more ram is being used untill i eventually run out of memory and the game crashes. (I'm looking at ddms here)
If my xml file has 50 objects, i can probably restart the game about 5 times, if i have 300 objects, i can only play only once.

I've looked on the forum but cant find anything that fixes it. I've tried world.disposeAll(), removing and reloading the textures. removing mesh data, etc.

Object polygon sizes are about 100 polygons each. Serialized
Level is about 2000 polygons.
Textures are all powers of 2, no bigger than 512x512 (compressed and 4bp) probably no more that about 2 for level and 5 for the frontend




I've run out of ideas so any help would be erm.. helpful.



Thomas.

Memory is free by garbage collector. You can try call this methods

Loader.clearCache();
MemoryHelper.compact();
System.gc();


or compress your textures by this
texture.compress();

EgonOlsen

Why are you keeping the world? Try to add a call to world.dispose(), null the world and create a new instance at resume.

dutch_delight

Thanks for the replies.

None of those seem to work though. :(
I've also added world.dispose() then null it and re initialize it. but the problems stays the same.

this is my log output: Is it running out when loading a texture?

05-11 19:59:21.359: E/AndroidRuntime(7571): FATAL EXCEPTION: GLThread 243
05-11 19:59:21.359: E/AndroidRuntime(7571): java.lang.OutOfMemoryError
05-11 19:59:21.359: E/AndroidRuntime(7571): at java.io.ByteArrayOutputStream.expand(ByteArrayOutputStream.java:91)
05-11 19:59:21.359: E/AndroidRuntime(7571): at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:201)
05-11 19:59:21.359: E/AndroidRuntime(7571): at com.threed.jpct.ZipHelper.unzip(ZipHelper.java:30)
05-11 19:59:21.359: E/AndroidRuntime(7571): at com.threed.jpct.GLRenderer.convertTexture(GLRenderer.java:860)
05-11 19:59:21.359: E/AndroidRuntime(7571): at com.threed.jpct.GLRenderer.setTextures(GLRenderer.java:2380)
05-11 19:59:21.359: E/AndroidRuntime(7571): at com.threed.jpct.GLRenderer.drawVertexArray(GLRenderer.java:2252)
05-11 19:59:21.359: E/AndroidRuntime(7571): at com.threed.jpct.World.draw(World.java:1354)
05-11 19:59:21.359: E/AndroidRuntime(7571): at com.threed.jpct.World.draw(World.java:1135)
05-11 19:59:21.359: E/AndroidRuntime(7571): at my.program.MyProgram$MyRenderer.onDrawFrame(MyProgram.java:4811)
05-11 19:59:21.359: E/AndroidRuntime(7571): at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1462)
05-11 19:59:21.359: E/AndroidRuntime(7571): at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1216)


The only thing that's zipped is my player model and that's 94kb uncompressed and 38k compressed.
Textures are always the same and are only loaded once at the start of the game.

I do create a layered texture for my level which is a 512 texture and a 128 tiled textured (tiled quite large) could that be it?
but the temporary object i create are nulled after I'm finished with them.


EgonOlsen

The textures will be zipped if you enable compression on them and they will be unzipped on context change. That's normal. If no memory is being freed after you dispose everthing, you are holding some references yourself somewhere, i assume...

dutch_delight

Ok. so it's not adding a texture or anything at that point?

Just been testing, and if I go back to the main menu and leave it for about a minute, there is an automated garbage collection (gc_concurrent), the memory is cleared and I can run the game again with all objects.

Do you know of anyway to speed up the memory clearing? I am calling system.gc() but that doest really help.

thanks

EgonOlsen

No, it's not adding a texture. It's upzipping the compressed pixel data to upload the result to the gpu. This has to be done each time the context changes. BTW...why are you disposing everything at the first place? Just keep all your Object3Ds and stuff where there belong and there will be no need to reload something and the memory isn't affected that much any longer.

dutch_delight

I'm disposing everything because I have 3 levels and they are populated by different buildings, towns, boats, airfields etc. and the object counts vary in each level.
I suppose i could try and re-use my models. I'll see how long that would take.

I'm also thinking of just adding a few delays to the menu and loading system to pad out the reset.




Thomas.

#8
textures probably take the most of memory, you can start with them
edit: it sounds interesting, any screenshot? :)

dutch_delight

No screenshots yet. Need to add some more scenery objects so the world looks more detailed. Hopefully it will (finally) be finished at the end of the month so you can play it yourself. I'll add it to the projects page once it's done.