Out Of Memory error?

Started by Disastorm, July 21, 2011, 03:45:33 AM

Previous topic - Next topic

Disastorm

Hello According to the MemoryHelper I was only using aroudn 10MB memory after compaction, but somehow I got an OutOfMemory error shown here:
http://i8.photobucket.com/albums/a23/Disastorm/OOM.jpg

How can I prevent this?  It happened when I added a whole bunch of objects into my scene (slowly added 1 at a time, through cloneObject).

*edit I saw in another thread you mentioned something about shareCompiledData.  That looks like it may have solved my OutOfMemory issue.
However it seems to work on all my objects except for my "enemies".  For some reason when I call it on them they become invisible... why is this?
also whats the difference between cloneObject and new Object3D(model, true) ? should i actually use the latter instead of cloneObject?  Also I noticed when I do shareCompiledData, my object flashes like brown for a split second when I add it to the world.  If i dont share the compiled data this does not happen.  Is there a way I can stop this flash of brown as it is a little annoying and makes me feel like my game is less polished.

EgonOlsen

#1
No idea what you are doing there...there shouldn't be any kind of "flash" or something when using shareCompiledData(), but as said, it's impossible to say what you are actually doing. If you can provide a simple test case, i'll have a look.

cloneObject() and new Object3D(<Object3D>) are two ways for doing the same thing. It doesn't matter which one you are using.

Edit: Where are you adding the additional objects? In the render thread or from outside the render thread? If the latter is the case, don't do that.

Disastorm

#2
its inside the render thread (btw this is a separate issue but I noticed alot of times in the logs it said my object wasn't built and it was forcing a build even though i have built it some time previous before cloning but I think when I build it after the clone also, then it gets rid of that message). 

here is where I originally instantiate the model before cloning (its the one called obj2):

                                Tower tower = towerMap.get(TowerType.LEAF_TOWER);
Object3D obj = Loader.loadSerializedObject(main.getResources().openRawResource(tower.getModelResourceId()));
obj.setScale(tower.getModelScale());
obj.setUserObject(tower);
tower.setModel(obj);

Object3D obj2 = new Object3D(obj, false);
obj2.setUserObject(tower);
tower.setAnimatedModel(obj2);

Object3D bullet = Loader.loadSerializedObject(main.getResources().openRawResource(tower.getBullet().getModelResourceId()));
bullet.setScale(tower.getBullet().getModelScale());
tower.getBullet().setModel(bullet);

bullet.setCollisionMode(Object3D.COLLISION_CHECK_SELF);

obj.build();
obj2.build();
bullet.build();



here is the clone method (the one called animatedModel is the one that flashes):

public Tower clone(boolean cloneStaticModel, boolean cloneAnimatedModel) {
Tower tower = new Tower(main);
tower.setCanAttackAir(canAttackAir);
tower.setCanAttackGround(canAttackGround);
tower.setDmg(dmg);
tower.setEffect(effect);
tower.setHeightPos(heightPos);
tower.setModelResourceId(modelResourceId);
tower.setModelScale(modelScale);
tower.setMsDelay(msDelay);
tower.setOnlyEffect(onlyEffect);
tower.setTile(tile);
tower.setTileRange(tileRange);
tower.setTowerName(towerName);
tower.setTowerType(towerType);
tower.setBullet(bullet);// no need to clone this
tower.setWorld(world);
tower.setPointRange(pointRange);
tower.setUseTileRange(useTileRange);
tower.setRangeCircle(rangeCircle.cloneObject());
tower.getRangeCircle().shareCompiledData(rangeCircle);

if (cloneAnimatedModel) {
tower.setAnimatedModel(new Object3D(animatedModel, true));
tower.getAnimatedModel().shareCompiledData(animatedModel);
}
if (cloneStaticModel) {
tower.setModel(model.cloneObject());
tower.getModel().shareCompiledData(model);
}

return tower;
}

here is part of my code where I add the Object (newTower.getAnimatedModel is the one that flashes brown) :

                float levelHeight = ((CreatureDefenseApp) main.getApplication()).getLevelHeight();

Tower newTower = tower.clone(false, true);
newTower.setWorld(main.world);
tile.setTower(newTower);
newTower.setTile(tile);
Object3D clone = newTower.getAnimatedModel();
SimpleVector center = tile.getCenter(levelHeight);
center.z = newTower.getHeightPos();

clone.build();
clone.setOrigin(center);


tile.setEnabled(false);
main.getTowerRunner().add(newTower);

Object3D rangeCircle = newTower.getRangeCircle();
SimpleVector rangeCircleCenter = tile.getCenter(levelHeight);
rangeCircleCenter.z = ((CreatureDefenseApp) main.getApplication()).getLevelHeight() - 0.02f;
rangeCircle.setOrigin(rangeCircleCenter);
rangeCircle.build();

main.world.addObject(clone);
main.world.addObject(rangeCircle);

EgonOlsen

Might be that the has-already-been-build-state isn't copied when cloning an Object3D. I'll have a look at it. About the flashes....i can't verify this. Can you create a simple, self-running test case that shows this problem?

EgonOlsen

I modified an animation test class of mine trying to reproduce this problem...but while i discovered and fixed another one (which shouldn't affect you), i wasn't able to reproduce it. Everything looks fine in my test case.

Concerning build() on cloned objects, i was wrong. It IS required to call it and if you don't, jPCT-AE will do it for you before rendering the object for the first time. I've changed the level of that message from warning to message to make it sound less dangerous.

Disastorm

#5
Ok thanks.  ill try to make a test case later, however, i managed to get a screenshot (from my phone) of the instant it flashes so maybe this can give u an idea of whats happening:
http://i8.photobucket.com/albums/a23/Disastorm/device-2011-07-21-105852.png

Also do u have any ideas about my enemies why they might become invisible if i share compiled data (i suppose its also possible that their scale changes so I can't see it or something else happens)?

EgonOlsen


EgonOlsen

About the screen shot: I guess the upper half of the upper left "thing" is correct and the lower half is wrong? Looks like, as if it's using the texture of the "knob" for the "leaves" (...or whatever that is). Or is this one texture that contains green and brown parts?

Disastorm

#8
This object uses 3 different texture files.   Oh you are right it does look like its using the texture of the knob, i didn't notice that.  Do you know why it would be doing that?  No I'm not using libgdx.  Btw yea my screenshot looks weird like split because apparently ddms.bat that i was using to take screenshots takes them like that, on the actual screen I don't believe its ever actually split in half like that.  What actually happens is the entire object looks like that for a split second and then it becomes normal, and this only happens when i set it to sharing compiled objects.

EgonOlsen

No...no idea why it is doing that. If an objects uses different textures, it will be split at compile time. Maybe that doesn't work correctly when sharing these compiled data. I'll try to reproduce the problem with this information.

EgonOlsen

I haven't created a test case yet, but i think i've found the problem by just starring at the code...

Disastorm

#11
Here is a test program http://www.sendspace.com/file/cqlcil

just run that and then double tap the screen to add the model and you should see the flash.  You might have to manually terminate the process after each run though since I didn't add in support for all those OnStop() and OnRestart and stuff.

oh yea u still havn't mentioned why my enemies might be invisible if i share the compiled data.

EgonOlsen

No idea about the invisible enemies, but the texturing/flashing issue should be fixed now. In addition, i found another problem in the same domain but when using VBOs. This should be fixed too. You can find the link to the new version in the "new version"-thread. Keep in mind that this version enables VBOs by default. Shouldn't be an issue though.

About the enemies...maybe this version fixes that too? I don't think so, but you never know. If not...test case?

Disastorm

#13
Thanks, both the flashing and the invisible enemies are fixed with this version. 

Btw when sharing meshes If I call animate on the original Object3D will all of them animate or do I still need to call animate on each one individually?

EgonOlsen

Animate the original is sufficient...everything else is just a waste of CPU cycles. I'm confused why this fix should fix the invisible enemies, but so be it... ;)