ThinkGeo.com    |     Documentation    |     Premium Support

RasterLayer Memory Usage after First Use

Suppose you have a series of RasterLayers in your WinformsMap that you increase in size and resolution as you go up in ZoomLevel.  The first raster image of the world would be relatively low resolution, and as you zoom farther in, you would likely split up higher resolution images, say, into 8 tiles to cover the world, visibile to higher zoom levels.


When you first load the map and load all these layers with a CurrentExtent of the whole world, the memory usage is low.  Then, when you zoom into a CurrentExtent that has a zoom level that includes the 8 tiles, the memory use goes up, as we would expect.


However, when you zoom back out, the memory use does not go down, even after some time and map refreshes.


Is there a way to change this behavior?  Thanks!



Brian, 
  
 Have you tried to call Close method? The Close method plays an important role in the life cycle of the layer, it should be called when you want to release the memory and other resources that were allocated since the open method was called. 
  
 We use the following pattern to deal with Layer, also derived to RasterLayer. 
 RasterLayer.Open(); 
 // between open and close, you can use the API of RasterLayer to do something. 
 RasterLayer.Close(); 
  
 If your problem is not this, please let me know what kind of image you use for RasterLayer and also provide us more information which can help to solve your problem. 
  
 Thanks 
 James 


I suppose you would need to monitor the ExtentChanged event, scan through the visible layers, determine which ones are not in use, and close them? 
  
 I end up opening them to call the GetBoundingBox method quite a lot.  It would be nice if you only had to do that the first time, then could close it, then GetBoundingBox would still work because it really will not change.

Hi Brian, 
  
 To make the map rendering more efficiently, we leave the layers open after drawing it to the map control. Opening and closing a layer cost much time, so if you close a layer when zoom out and open it when zoom in, the performance is not very good if the data is very big and the zoom in and zoom out operation happens frequently.  
  
 Any more questions please let us know. 
  
 Thanks, 
  
 Sun 


Hmm, so it sounds like James’ idea will not work well.  Is there any other way to ‘free ram’ (i.e. garbage collect) when a set of images is not required at this zoom level? 
  
 What happens is that when I first load, memory usage is low.  Then I zoom into the higher resolution JPG files in 8 tiles of the world.  Then memory usage goes way up.  When I zoom back out, it does not go down – even after many minutes and map extent and refreshes.  I’m wondering if there is a way to force it to the original state without reloading everything.

Brian,



  From my experience usually people stay away from using Jpeg, Bitmaps, PNGs etc because of the memory footprint of the reader. What I mean be that is the methods for reading these kinds of files usually load the entire image into memeory becasue they are typically used for photos or small images and not really huge GIS images.  For GIS the main file raster formats are TIFF, ECW, JPEG2000, and MrSid.  The thing they all have in common is that their readers are designed to use a minimum of memory and not to load the whole image into memory.  They are designed to read gigabyte sized image effeciently.  At a fundamental level I think the issue may be with the JPEGs themselves.  No matter if we could garbage collect etc the method to load the image would require loading the entire image and then scaling it in memory.  With the other formats above you can get scaled images without loading the entire image into memory.  They have special file formats using wavelet and other technology which allows them to store the image at multiple resolutions in the same file with a relatively low overhead.



  I would suggest that if you can convert these files to ECW using their free compressor or to JPEG2000.  You could also save it as a TIFF at the same resolution but TIFF, while optimized a little, can still be a bit slower then the ECW, MrSid, and JPEG2000.  My first choice would be to see if you can convert them.  If you really need to use JPEG and you want to unload them from memory then we can close and open on demand.



I have created a small sample showing you how to close the raster layer after itself.  It inherits from the GdiPlusRasterlayer and then overrides the DrawCore.  I call the base classes Draw then after that I call the close and then do a garbase collection.  I am not sure how this will work for you but you can give it a try.  This also shows you a little bit of the power of inheritence in our model.  It's much better then hooking events. :-)  let me know if you have ani ideas or need clarification on anything.



David






    public class SelfClosingGdiPlusRasterLayer : GdiPlusRasterLayer
    {
        protected override void DrawCore(GeoCanvas canvas, System.Collections.ObjectModel.Collection<SimpleCandidate> labelsInAllLayers)
        {
            base.DrawCore(canvas, labelsInAllLayers);
            this.Close();
            GC.Collect();
        }
    }
 



I liked the inherited class approach and tried it, but quickly realized that it would create problems for me. The reason is that my application has a container with RasterLayer elements in it. Creating static implicit operators to convert from and to 'SelfClosing' was not easily possible for me.   The other problem with the inherited override approach was that I could not centrally control closing and garbage collection.  Basically, I want to do that when I'm fairly certain the user has stopped moving about for a while.



What I ended up doing, which is quite fast, is to simply close the raster layers in my container that are not in view at the current zoom level or within the CurrentExtent. When I detect a new Close, I do a garbage collection in the background. Works like a charm.



Brain, 
  
 Thanks for your post and letting us know your status. 
  
 Just feel more to talk about here for more discussion. 
  
 Thanks. 
  
 Yale