This content has been marked as final. Show 17 replies
you used up so much memory beacuse you have all 1000 images in memory at a time. You must load them as you need them in order to optimize this.
Fortunatelly the TileList container is designed to do this and you should use it. If you combine it with a custom itemRenderer you'll need no code to achieve what you are looking for.
Thank You for your quick answer
The main idea of my application is to show animation of some layers ( Canvas which contains set of images). So, I have a set of canvases (each of them contains set of images/tiles). To do animation at first I have to load all images into the appropriate canvases (containers) an then show necessary canvas (animate).
In that case I guess you are in trouble, my recomendation is that you consider optimizing your code. If what you are trying to achieve is a transition between canvases then you only need 2 canvases at a time, I guess you can make your code add canvases dynamically as needed instead of all at one time.
You can still preload all the images so you'll be able to display them quickly, to do this you can use 2 or 3 image containers to download all the images, even if you destroy the image immediately after download it will stay in the browser cache, so next time you load the image in a image container it should load pretty fast. Since you are handling 90 MB of data though this can take some time.
I am just trying to understand why there is so much memory being used. All 1000 tiles are ~10Mb. At the beginning the application (browser) uses ~40Mb, and after tiles loading it increases to ~300Mb. The reason is that for each image the new object is stored into the memory?
Is it possible to use any advantages of Bitmap object? I mean to draw one bitmap (which will contain all tiles) for each canvas.
I suppose you can, but remember that when you see the file size you are looking at JPG compressed images, when flash access them it has to decompress them into memory. I guess that's the reason your memory size goes all the way to 300 MB.
If you come to think of this having all images in one Bitmap should use more or less the same amount of memory. Still I'm not sure how flash manages its internal memory.
I can't help you with your application as it is currently constructed but I may be able to shed some light as to why so much memory is being used. Flash cannot display .jpg images as such. It converts every image loaded into a bitmap. So even if you have a miniscule 15x15 gif file (approx 370 bytes) loaded into the FlashPlayer (for example, via the Image class) it gets displayed as a 15x15 bitmap with 3 or 4 bytes per pixel (depending on whether it uses the alpha channel). So now FlashPlayer is using 900 bytes of memory for your image.
And as I think you guessed, if you use the same .gif in 4 Image class instances, each one gets loaded into its own memory location for 900 x 4 = 3,600 bytes of memory used.
Just to give you a heads up, if you try removing the Image class after you are done with it, the bitmap data will still stay in memory causing a very serious memory leak. Although this is beyond the scope of your current application (as I understand it) it will need to be addressed by accessing the Image.content as a BitMap and then calling dispose() on the BitMap.bitmapData. I only say this now because in my experience, anytime someone is loading images dynamically in their application, they inevitably end up wanting to unload them later. So again, for future prosperity, remember to dispose your bitmap data before you remove your Image classes:
likewise, if you are smart(er than me) you might be able to create a bitmapData instance for shared images and pass a reference to that to Bitmaps that are being displayed in your application. Again, this will only theoretically help you if you are using the same image multiple times.
Sorry but these are the only suggestions I can make to help cut down memory usage when dynamically loading external images--and these tips might not even apply to your current goal.
Now I better understand how the Image's object is stored into the memory.
Thanks for the valuable advice concerning bitmap data disposing. It really helped in case of unnecessary images removing.
From reading to your explanation I ended up a little confused; are you saying that garbage collector wont destroy the image data once you dispose of the object?, lets say I have a sprite with 4 Loader classes that each loaded an image, if I remove every reference to the Sprite, and the garbage collector take care of it, and later of the loader classes since they ended up with no reference, the image data will still be eating up memory?
Originally posted by: buabco
are you saying that garbage collector wont destroy the image data once you dispose of the object?, lets say I have a sprite with 4 Loader classes that each loaded an image, if I remove every reference to the Sprite, and the garbage collector take care of it, and later of the loader classes since they ended up with no reference, the image data will still be eating up memory?
In essence, yes, that is what I am saying. However, I must add the caveat that I am not privy to the inner workings of the garbage collection system. What minimal knowledge I do have I picked up from gskinner.com (www.gskinner.com/blog/). Last year another forum user was having the same trouble and he ended up posting on gskinner's blog and he was able to figure out that the bitmap data had to be disposed. And he also provided some explanation as to why.
In my case I had a component that used an Image class to load external bitmaps. I tried many different implemenations varying the following two themes:
1) Single Image class that dynamically loaded different .jpgs
2) Single parent class that dynamically loaded different Image classes for each .jpg
whether changing the content of the Image, or removing the Image class entirely and creating/adding a new Image, I found that flash was holding onto the bitmap data. Since my images were 2000x1500 pixels I rapidly ran out of memory.
However, I was not able to crash my computer the way a true memory leak should. What I found is that when I got to about 90% of my RAM, then Flash player started recycling data. My only guess is that the player decided on its own "well, I gotta get rid of something or I'm gonna crash" and therefore finally started disposing (I assume) bitmap data. However, like I said, I have no way of knowing for certain--it's just my speculation. The player could easily have been disposing of other information as well, although the sheer volume of bitmap data in memory means that, if data was chosen at random by the garbage collector, the bitmap data was most likely removed.
This is one of those things where I really wish someone at Adobe or a Flash player engineer would enlighten the community.
Me too I wish I could have some recomendation form Adobe on the right way of preparing data for disposing. All I know now is that you should remove every reference to an object in order to for the garbage collector to kill it. This is kind of tricky when you are using events since you need to remove event listeners from an object so it will be disposed, I wonder why there is no deletion command on the flash framework.
I'm not sure ether how or when the player performs the garbage collection, there is no command to force it, so you should relly on it. For what I can read on your own experience it seems that the Player tends to use garbage collection as the only last resort when it's running out of memory which doesn't look very good.
Still, I'm writting an application that should end up using lots of images, I'm not using the IMAGE class but a sinple Loader, I haven't check on the memory usage yet, but I'll write here what I found.
Just to let you know, the Image class actually contains a Loader inside of it. The Loader's property name is "content".
Also, garbage collection does occur periodically. You can see this if you watch your resource manager. What I was trying to say is that when the player is running extremely low on resources, it seems to force garbage collection on resources it might not consider true garbage as a safety precaution. Presumably, if it had endless resources, it would not do so. Anyway, just wanted to clarify, garbage collection definately does work, just not for bitmap data.
I'm interested in the sharing aspect you mention. Have you tried this? Any help would be appreciated.
I have not tried sharing with bitmaps or bitmapData objects yet. I have done sharing with simple XML data, URLLoader data, and DisplayObjects. The concept should basically be the same, though. My only hesitation is that bitmaps are terra incognito for me.
However, if I were to try it, I would make a static bitmap data variable for some custom AS class that is similar to the SWFLoader or Image class (or even extends from them). Anyway, I will assume I have a class that displays a bitmap. I may have more than one of these classes on the screen at a time. The class will extend from a regular UIComponent and contain a Bitmap instance. However, the class will have one globally accessable (static) BitmapData class instance. Use a class initialization technique similar to that used when making custom styles to call a method the first time any instance of this class in instantiated. In that method set up your BitmapData class instance. In the regular instance constructor (or createChildren method or wherever), set the Bitmap instance's bitmapData reference to the static class reference. That should do it. You can set filters independently and show the same image on screen multiple times (hopefully) without getting tons of redundant bitmap data instances the way (I suspect) you do if you try the same thing with Image or SWFLoader.
Like I said, I do this with ComboBox dataProviders where the dataProvider is taken from an external XML but I have multiple instances of the same ComboBox/dataProvider in one application (although I have the added incentive because the XML is furthermore taken from the server and I don't want to call the server EVERY time a combobox appears--but that's neither here nor there). Anyway, though, like I said, the same priniciple should apply here as well.
And if you want to dynamically apply the same technique for any number of bitmap data (such that any one bitmap data is only loaded once and then never again), it shouldn't be too big a leap to set up a Dictionary (or just a regular array if you like) and then load the images from there to the appropriate instances based on some key value.
I'm sorry I don't have any code worked out. But if you 're interested (and what I described above makes sense), then give it a whirl. If you have problems, post them.
Could you give any idea about such approach. I am going to load all necessary images using URLLoader and store them into the ByteArray. When the animation starts I will show necessary images from ByteArray ( using Loader.loadBytes() ). How to represent loader's content as UIComponent (e.g. to put it into canvas container) and then how to dispose this bitmap from UIComponent?
I think I actually did this, even though I thought I was copying the bitmap, since it was more than one copy of the image on the stage.
What I did is something like this:
var ldr:Loader; //Lets asume this is the loader you used to load the image and the image is already loaded, I'll not add the code to actually load the image here.
var bmp:BitmapData = new BitmapData(ldr.width, ldr.height); //Try use the real width and height here
var copy:Bitmap= new Bitmap();
copy.bitmapData = bmp;
Do you know what the significant difference between Loader and URLLoader classes is?.. and what is better to use for PNG images/tiles loading?
They are totally different, and they are used for totally diferent things as well. The URLLoader is meant to server side script communication, you can get a PNG from it but you'll just get the PNG data, not sure how you go from there to a display object, I don't think you can any ways, since what URLLoader provide is RAW data.
The Loader class on the other hand is a DISPLAYOBJECT and is meant to load IMAGES and SWF files you'll use on your stage. This class does all the uncompressing of Images for you and just gives you a display object in it's "content" parameter.
I totally recommend you the Loader class for image loading.