How does the Virtualizer work?

Started by kiffa, September 04, 2012, 07:16:06 AM

Previous topic - Next topic

kiffa

I want to use the Virtualizer class of jPCT-AE to resolve OOM, and i have read the doc, but i want to know a little more, thanks.

The process of my app is like this:

Load all models(.ser and .bones) ->
entry Scene1 -> Load all textures which are used in scene1 only -> some logic\event\draw ->
switch to Scene2 -> removeAndUnload all textures(Config.unloadImmediately = true) ->
entry Scene2 -> Load all textures which are used in scene2 only -> repeat like scene1 ... ...
-> switch to SceneN ... ...

And the OOM usually happened in the stage of "entry new scene -> load textures", my question:

1, Does the process of loading texture need more memory(peak) than the texture itself? For example:  new Texture("1024X1024.jpg"), the texture will consume 1024x1024x4 bytes of memory finally, but does the process of "new Texture(like io、decode-jpg and so on)" need more memory than 4MB?     

2, Does TextureManager.removeAndUnload () guarantee freeing memory immediately ?

3, Does the follow memory-route right?

new Texture(1024X1024) -> 4MB

set Virtualizer -> set context -> virtualize the texture -> swap the texture from vm to disk(flash) -> 0MB

Frambuffer.draw() -> upload the texture to GPU -> I don't know what happen with the virtualized-texture in this stage, help please.

removeAndUnload the virtualized-texture -> what happened?

Does the virtualized-texture need be swapped back(from disk to vm) in any situation? When? Does the process of virtualizing need more memory(peak) than the texture itself? How much time does the process of virtualizing consume typically?

4, Seems there are enough memory in every scene of my app(all of them can run fine alone),  but OOM happened in the scene switching, any suggestions? Many thanks! I have reduced my texture to two jpg(512X512) per scene, and it's hard to reduce more. And i also enabled Texture.4bpp, disabled Texture.Mipmapping.

EgonOlsen

Quote
1, Does the process of loading texture need more memory(peak) than the texture itself? For example:  new Texture("1024X1024.jpg"), the texture will consume 1024x1024x4 bytes of memory finally, but does the process of "new Texture(like io?decode-jpg and so on)" need more memory than 4MB?     
Yes, it will. The additional memory is needed for storing the decoded image before uploading it. However, this memory is controlled by Android's Bitmap class and i have no influence on it.

Quote
2, Does TextureManager.removeAndUnload () guarantee freeing memory immediately ?
Yes, if you set Config.unloadImmediately=true. You can check this by setting the Logger to debug.

Quote
Frambuffer.draw() -> upload the texture to GPU -> I don't know what happen with the virtualized-texture in this stage, help please.
It will be loaded from disk and uploaded to the gpu. Then the memory used to load it will be freed. You should be able to track this process in the logs.

Quote
removeAndUnload the virtualized-texture -> what happened?
It will remove the texture from the gpu just like it would do it with any other texture.

Quote
Does the virtualized-texture need be swapped back(from disk to vm) in any situation? When?
When uploading it to the gpu (for the first time, after an unload-call or after a context change).

Quote
Does the process of virtualizing need more memory(peak) than the texture itself? How much time does the process of virtualizing consume typically?
Yes. it uses the same amount as any other upload does (i.e. gpu memory + main memory). The difference is that the main memory will get freed after the upload.

Quote
4, Seems there are enough memory in every scene of my app(all of them can run fine alone),  but OOM happened in the scene switching, any suggestions? Many thanks! I have reduced my texture to two jpg(512X512) per scene, and it's hard to reduce more. And i also enabled Texture.4bpp, disabled Texture.Mipmapping.
Make sure that you null all old references before assigning new values, i.e.


obj=null;
obj=new Object();


instead of


obj=new Object();


I don't see how 2 512*512 texture can cause a problem unless something else consumes huge amounts of memory. Have you really sure that your memory is going where you think it does?

kiffa

#2
Sorry, there are 3 512X512 jpg in the largest scene, not 2.

And the memory map is roughly like this:
1, Damn android-system-res - 4M+

2, dog.bones(a model of 6000+ trangles with 2000 frames animations)  -  5M+

3, textures of models, about 512*512*4*3 + 512*512*2*3(gpu) = 4.5M(Do i calculate correct?)

4, some 2D textures, used for Framebuffer.blit(), and i don't know how does the memory use and free in this stage.

5, some images(some are large - 800X480) used for the Dialog class of android sdk (to implements the full-screen-menu), my friend do this, so i don't know the details clearly.

6, some .ser models - 6000 trangles at most.

7, other data structures with a little memory usage.

And i have reduced the textures to 2 512*512 plus 1 256*256,  the dog-animation to 1500+ frames, this help much.

But i really want to free the android-sys-res....

kiffa

#3
And you say:

obj=null;
obj=new Object();


insted of

obj=new Object();

I am a new  Javaer, could you explain more? Does the previous code make the GC happier(So, the memory of the obj will be freed fastter)?

EgonOlsen

Quote from: kiffa on September 05, 2012, 10:43:47 AM
I am a new  Javaer, could you explain more? Does the previous code make the GC happier(So, the memory of the obj will be freed fastter)?
The latter one consumes twice the memory while creating the new instance because it will be assigned to obj after the creation. Until then, both the old and the new instance exist and neither will be garbage collected.

kiffa

I got it, thanks!

And could you explain the memory usage when Framebuffer.blit()?

new texture -> Framebuffer.blit() -> Then what happend? Upload the blited texture to gpu? And when free it?

EgonOlsen

Quote from: kiffa on September 06, 2012, 04:28:38 AM
Then what happend? Upload the blited texture to gpu? And when free it?
Yes, upload it once and never free it unless you request for it by calling unload. It's the exact same behaviour as if you were using the texture on an object.