www.jpct.net

jPCT-AE - a 3d engine for Android => Support => Topic started by: Disastorm on July 21, 2011, 03:45:33 am

Title: Out Of Memory error?
Post by: Disastorm on July 21, 2011, 03:45:33 am
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.
Title: Re: Out Of Memory error?
Post by: EgonOlsen on July 21, 2011, 11:05:10 am
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.
Title: Re: Out Of Memory error?
Post by: Disastorm on July 21, 2011, 11:54:53 am
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):
Code: [Select]
                                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):
Code: [Select]
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) :
Code: [Select]
                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);
Title: Re: Out Of Memory error?
Post by: EgonOlsen on July 21, 2011, 12:02:13 pm
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?
Title: Re: Out Of Memory error?
Post by: EgonOlsen on July 21, 2011, 03:01:02 pm
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.
Title: Re: Out Of Memory error?
Post by: Disastorm on July 21, 2011, 08:01:58 pm
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)?
Title: Re: Out Of Memory error?
Post by: EgonOlsen on July 21, 2011, 08:15:22 pm
Are you using libgdx?
Title: Re: Out Of Memory error?
Post by: EgonOlsen on July 21, 2011, 08:18:16 pm
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?
Title: Re: Out Of Memory error?
Post by: Disastorm on July 21, 2011, 08:48:25 pm
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.
Title: Re: Out Of Memory error?
Post by: EgonOlsen on July 21, 2011, 09:06:16 pm
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.
Title: Re: Out Of Memory error?
Post by: EgonOlsen on July 21, 2011, 09:37:00 pm
I haven't created a test case yet, but i think i've found the problem by just starring at the code...
Title: Re: Out Of Memory error?
Post by: Disastorm on July 21, 2011, 09:47:17 pm
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.
Title: Re: Out Of Memory error?
Post by: EgonOlsen on July 21, 2011, 11:48:24 pm
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?
Title: Re: Out Of Memory error?
Post by: Disastorm on July 22, 2011, 12:01:17 am
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?
Title: Re: Out Of Memory error?
Post by: EgonOlsen on July 22, 2011, 11:00:56 am
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... ;)
Title: Re: Out Of Memory error?
Post by: EgonOlsen on July 22, 2011, 11:54:53 am
I thought it might be helpful to somebody, so i wrote a little page for the wiki that briefly explains some techniques to save memory: http://www.jpct.net/wiki/index.php/Reducing_memory_usage (http://www.jpct.net/wiki/index.php/Reducing_memory_usage).
Title: Re: Out Of Memory error?
Post by: Disastorm on July 22, 2011, 09:47:48 pm
Thanks for that link.  It has a few things I wasn't doing like compressing meshes and whatnot so that should help.  I have another question.   If I have a bunch of the same object is it better (in terms of memory) to have them as separate cloned objects sharing compiled data, or perhaps to merge them all into a single Object3D?

Also I noticed it says to compress keyframe animation meshes, but should I also compress the main object's mesh?
Title: Re: Out Of Memory error?
Post by: EgonOlsen on July 23, 2011, 08:58:04 am
Merging stuff is always faster and uses less memory. So if possible, merge them. You can compress the object's mesh too, but depending on the way it was created, it might be compressed already. The gain from compressing meshes usually isn't that high.
Title: Re: Out Of Memory error?
Post by: Disastorm on July 24, 2011, 01:22:12 am
hey question what would happen if you merge a non-animated object with an animated one.  will it become animated and keep the animation of the object?

Also you say merging is always less memory, by why does the javadoc say:

"Merging objects is quite expensive in terms of memory usage."

And also it looks like when I merged it actually did ended up taking more memory:
4993 to 5018 after initialization
Title: Re: Out Of Memory error?
Post by: EgonOlsen on July 24, 2011, 05:13:14 pm
Merging is memory intense, not the merged result. Simply because in the process, you need twice the memory that the objects to be merged require. After that, memory usage is a bit lower. Your numbers are so close together that i wouldn't even worry about it. In general, merging reduces instance count in main memory and on the GPU. It also allows the engine to process the geometry faster. If you are able to merge, then merge.
Title: Re: Out Of Memory error?
Post by: Disastorm on July 25, 2011, 11:25:40 am
Ok thanks.  Also another question about merging, does it matter if you merge clone objects as opposed to real objects? The final result should be the same either way right?  Also what about animated objects? I should keep that separate from non animated objects?
Title: Re: Out Of Memory error?
Post by: EgonOlsen on July 25, 2011, 09:43:51 pm
Merging cloned objects...doesn't make much sense, does it? Why not merge the blueprint object multiple times instead of creating a clone and merging that. Merging animated objects doesn't work...or at least you'll lose the animation, so i guess it's save to say that it "doesn't work". It might not be a smart either, because it would increase the time needed for vertex updates. I suggest to merge static geometry at startup if possible but don't bother with merging animated objects somehow.