April 16, 2008

Papervision3D 1.5 Material-Caused Memory Leak

Filed under: Flash — Jackson @ 9:28 pm

Working on a large Papervision3D project, I had begun to notice a constant increase in RAM usage as the Scene was running. This particular scene does a lot of updating of BitmapMaterials and Planes, responding to user input by transforming a thumbnail plane into a larger full view plane. The animations run about 1 second, with roughly (on faster machines) 30 frames per second. On most machines out in the ether I’m hoping to maintain 20 FPS.

So, what I noticed was that there was a pretty large spike in memory usage when the scene first loads–no problem, I’m loading a couple hundred images in, I should expect that. However, I noticed also that as I transitioned from one image to the next (the smaller to the larger), RAM use would jump up about 10 megabytes. Where is garbage collection when I need it?

The trouble turned out to be that I was re-instantiating a BitmapMaterial object during each from of the animation. For whatever reason (I haven’t had time to walk through the BitmapMaterial and MaterialObject3D classes carefully yet), BitmapMaterial objects seem never to leave memory. The issue may be more complex than this though, as I’m also reinstantiating a plane each frame as well to accommodate the changing siz. Perhaps the Plane is not leaving memory either?

Combing the web, I found an article on the Papervisio3D 2.0 Alpha “Great White” (http://thebackbutton.com/blog/47/materialmanager-memory-leak-in-papervision3d-great-white/) in which he mentions the whoas of a certain Singleton object that goes by the name of MaterialManager.

I scrubbed my Papervision3D 1.5 hierarchy for the same and found nothing. Looking a little further though, I found in the SceneObject3D class a reference to a class called MovieMaterial, which has in it a Singletonish static method called updateAnimatedBitmaps. This function references the animatedMaterials dictionary, containing (presumably) references to every material in the Scene including the one’s that I want, expressly, to die.

My apologies to anyone expecting a clearer outline of what’s going on with the animatedMaterials dictionary. You won’t find it here. You will however find a couple of fixes for this particular flavor of memory leak.

The first fix I found was to create a private class property of a BitmapMaterial object for each item that gets displayed. The class arrangement I am using has an composed DisplayObject3D inside of a class that handles event assignment, etc. So, by instantiating this BitmapMaterial once and simply changing it’s texture property each frame of animation instead of reinstantiating it, the animatedMaterials dictionary doesn’t get bloated with invisible BitmaMaterials, and the RAM uses stays where it should. Each frame I would then reapply the material to the newly resized plane.

A second fix, taking a note from Alex Bustin (see link above), is to simply comment out the lines of code in the SceneObject3D class that run the updateAnimatedBitmaps function. Both of these fixes seem to do the trick, I’ll leave it up to you decide which feels better.

I hope someone else might find this useful. Maybe you can spare yourself the three hours of trouble shooting. =P.

No Comments »

No comments yet.

RSS feed for comments on this post. TrackBack URL

Leave a comment

You must be logged in to post a comment.

 Nashville Web Design, Jackson Gabbard

Me and websites? We been knowing eachother since gradeschool.