I think that this is a flaw in the 3ds-loader.
I did a simple test: loading 1000 times the same 3DS file:
for (int i=0; i<1000; ++i) {
Object3D[] objects = Loader.load3DS("pesanthouse.3ds", 0.03f);
objects = null;
System.gc(); System.gc(); System.gc(); System.gc();
System.out.println("["+i+"] mem usage:"+((Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())/1024/1024)+"MB." );
}
But even after 1000 iterations, the memory consumed remains to 0MB.
So I think it's more closely related to the content of the Object3D class.
I did some other benchs by watching the memory consumption when instanciating lot's of objects with a various amount of triangles:
// the getPlane 'quad' parameter is the value I change
// note calling obj.build() and world.addObject(...)
// has no effect on memory consumption.
Object3D[] objs = new Object3D[1000];
for (int i=0; i<1000; ++i) {
objs[i] = Primitives.getPlane(10, 1.f);
objs[i].build();
System.gc(); System.gc(); System.gc(); System.gc();
System.out.println("["+i+"] mem usage:"+((Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())/1024/1024)+"MB." );
world.addObject(objs[i]);
}
Here are the results:
getPlane(2, 1.f); => 8 triangles / object
=> 126 objects / MB
=> 1008 triangles / MB
getPlane(6, 1.f); => 72 triangles / object
=> 66 objects / MB
=> 2376 triangles / MB
getPlane(8, 1.f); => 128 triangles / object
=> 18 objects / MB
=> 2304 tirangles / MB
getPlane(10, 1.f); => 200 triangles / object
=> 13 objects / MB
=> 2600 triangles / MB
getPlane(30, 1.f); => 1800 triangles / object
=> 1.5 objects / MB
=> 2700 triangles / MB
getPlane(60, 1.f); => 7200 triangles / object
=> 55 MB for 21 objects
=> 0.382 object / MB
=> 2750 triangles / MB
getPlane(120, 1.f); => 28800 triangles / object
=> 44 MB for 4 objects
=> 0.0909 object / MB
=> 2617 triangles / MB
Let's dicuss about the results:
- the average memory consumption is around 2700 triangles per megabyte comsumed (I don't rely on results when quad<8, which is not representative, as the memory consumed by the class itself has a big impact). This leads to a memory consumption of 388 bytes for each triangle (to give an idea it's the amount of place taken by 97 float values, or 32 vectors).
note: the results are in line with the memory consumption of my 3DS file (after merging) : 37MB for almost 100k triangles.
=> This looks really high.
In Object3D API, it seems that all information needed by a trinagle is:
public int addTriangle(SimpleVector vert1, float u,float v,
SimpleVector vert2,float u2,float v2,
SimpleVector vert3,float u3,float v3,
int textureID, int sec)
Which is something like 17 * 4 bytes = 68 bytes of 'relevant' data (to be compared with the 388 bytes found above).
Thus i suppose this data may be stored internally inside one or several object instances (<= I mean 'java object' here, like SimpleVector(s) or any internal 'Triangle' class).
Maybe that's the main cause of the overhead.
Another point: i discovered the ID of the sector is stored for each triangle. Wouldn't it be more efficient to only store the sector's ID for a whole object instead ?