The following forum(s) are migrating to a new home on Microsoft Q&A (Preview): Developing Universal Windows apps!

Ask new questions on Microsoft Q&A (Preview).
Interact with existing posts until December 13, 2019, after which content will be closed to all new and existing posts.

Learn More

 none
Memory leak with images RRS feed

  • Question

  • Hi,

    according to this thread http://social.msdn.microsoft.com/Forums/en-US/windowsphone7series/thread/6d3ee4fe-80ce-4813-a200-e1079cd1f645 I still haven't found a solution for displaying multiple images on one page. The images all are JPEG files and markes as content. After loading 10 of these images, the memory gets filled up and never is released. I tried to call the garbage collector manually, set the imageSource to null and anything else I found. There must be somebody here who has solved this problem?!

    Thanks in advance, Axel

    Sunday, January 16, 2011 4:15 PM

All replies

  • Hi Schulz,

      Yes, you have tripped across a known issue.  From my research into it, it happens when you use GetImage() but isn't directly a bug in the GetImage API itself.  Hopefully this will get fixed in an update sooner or later. 

      For the time being I did see one mechanism mentioned that you can try leveraging:

     

     

        PictureCollection pictures = mediaLib.Pictures;

     

     

     

        if (pictures.Count > 0)

     

        {

     

     

            using (Picture pic = pictures[0])

     

        {

     

     

        BitmapImage bmp = new BitmapImage();

     

        System.IO.

     

    Stream stream = App.GetResourceStream(new Uri("PictureLeak;component/bug.jpg", UriKind.Relative)).Stream;

     

        bmp.SetSource(stream);

        img.Source = bmp;

    }

      While you might see a temporary increase in memory using this approach, it should not leak like you're noticing when using GetImage.

      I hope this helps,

    ~Jonathan Tanner [MSFT]

    Monday, January 17, 2011 10:15 PM
  • Are you using the XNA Picture API or are you talking about images in your project? If the Picture API, there is a known memory leak in the ImageStream class it returns, however if you're loading images that you packaged with your project in Visual Studio, then you're not going to hit that bug.
    Monday, January 17, 2011 10:28 PM
  • Hi, thanks for the replies.

    This is not an XNA project. Currently I'm loading the images from the project the following way:

    BitmapImage

     

    image = new System.Windows.Media.Imaging.BitmapImage(uri);

    But I will try it with the using statement.

    Thanks,

    Axel

     

    Tuesday, January 18, 2011 6:14 AM
  • Hi Axel,

    This recent post may also be worth a look.. suggesting an approach to avoid memory leaks wrt image handling.

    Wpf Wonderland » Blog Archive » Images and memory leaks in Windows Phone 7
    Tuesday, January 18, 2011 10:37 PM
  • Hi, thanks for the replies.

    This is not an XNA project. Currently I'm loading the images from the project the following way:

    BitmapImage

     

    image = new System.Windows.Media.Imaging.BitmapImage(uri);

    But I will try it with the using statement.

    Thanks,

    Axel

     

     



    Did you figure out a work around for this?
    Monday, March 7, 2011 3:35 AM
  • You may find a resolution here (Towards the bottom):

    http://social.msdn.microsoft.com/Forums/en-US/wpdevelop/thread/e04fba43-2676-4607-b5ca-5f2ba9f2a875#8afe55f3-9b4e-485d-a117-56c903b13697
    Tuesday, March 8, 2011 5:04 PM
  • Hi All and Hallo Axel Schulz! :-)

    I think there is a bit of misleading information here in this thread. It seem from the original description that this memory growth is not caused by XNA's Picture.GetImage() or by the Toolkit's ContextMenu, as some posts/links suggested.

    So let us first establish whether or not this is a leak. It looks like you are creating the BitmapImage from URI. In this case, the platform caches the decoded image in memory for the lifetime of the application. This is an intended performance optimization so that the next time you go back to the same image we don't have to download and decode the image again which is very expensive. But in your scenario you may not want/need this cache and it may be the reason for the memory growth you experienced.

    In order to avoid or clear the cache, you have two options:
    a) for BitmapImages created from URI, set the UriSource on it to null when it's no longer needed. This will get rid of the cache.
    b) create the BitmapImage from a stream (instead of URI) to begin with. This will avoid creating a cache.

    If this doesn't work in your case please send me your repro project and I will help you work through this [swick at microsoft.com]

    Btw, as a side note, I am wondering how large your images are. If things already break down after 10 images they might be fairly large and you should consider re-encoding them to a lower resolution anyway for performance reasons. Keep in mind that the display is only 800x480, so if the image is considerably larger you might pay for a lot of pixels that you may not need.

    Thanks,
    Stefan Wick

    Microsoft Silverlight
    Wednesday, March 9, 2011 8:20 AM
  • Hi Stefan,

    the creation of the image from a stream works for the dynamic loading of images. This seems to work for the memory leak problem. I still haven't found time to create a bigger example, but I will try it next month.

    The images are around 40-250kb. This is because I want the ability to zoom into the pictures, which requires some level of quality. I also tried to reduce their size and changed the pngs to jpegs, but even with smaller images this didn't work. With the stream solution this works fine.

    The solution with setting the UriSource to null didn't work. I tried to do this that way, but the memory still increased. I removed every pointer to the image object und did a manual garbage collection. I don't know why this didn't work.

    So thanks for the answers,

    Axel

    Wednesday, March 9, 2011 8:57 AM
  • Axel, here is just a quick example to see that setting UriSource to null releases the cached image memory. If you remove the red line in the sample code then you will see from the memory counter that the decoded image remains cached in memory.

    <Grid x:Name="LayoutRoot" Background="Transparent">  
        <StackPanel> 
            <TextBlock x:Name="memoryCounter"/>  
            <Button Content="Add Image" Click="ButtonAdd_Click"/>  
            <Button Content="Remove Image" Click="ButtonRemove_Click"/>  
            <Grid x:Name="imageHost"/>  
        </StackPanel> 
    </Grid> 

    public MainPage()  
    {  
        InitializeComponent();  
        DispatcherTimer timer = new DispatcherTimer();  
        timer.Interval = TimeSpan.FromSeconds(2d);  
        timer.Start();  
        timer.Tick += new EventHandler(timer_Tick);  
    }  
     
    void timer_Tick(object sender, EventArgs e)  
    {  
        memoryCounter.Text = Microsoft.Phone.Info.DeviceExtendedProperties.GetValue("ApplicationCurrentMemoryUsage").ToString();  
    }  
     
    private void ButtonAdd_Click(object sender, RoutedEventArgs e)  
    {  
        Image image = new Image();  
        BitmapImage bitmap = new BitmapImage(new Uri("/test.png", UriKind.Relative));  
        image.Source = bitmap;  
        imageHost.Children.Add(image);  
    }  
     
    private void ButtonRemove_Click(object sender, RoutedEventArgs e)  
    {  
        if (imageHost.Children.Count > 0)  
        {  
            Image image = imageHost.Children[0] as Image;  
            if (image != null)  
            {  
                (image.Source as BitmapImage).UriSource = null;  
            }  
            imageHost.Children.Remove(image);  
        }  
    }  
     

    If this doesn't work in your case then there might be something else holding on to the image. We would need to look at an example for that.

    Thanks,
    Stefan Wick

    Microsoft Silverlight
    Wednesday, March 9, 2011 9:19 AM