Release images from IImage array to free up RAM?

J

juvi

OS........: [CE 5.0 / WM5.0 / WM6.0]
Hardware..: [HTC TOUCH DIAMOND]
Processor.: [Qualcomm MSM7201A]

I am trying to implement a "change theme" functionality in my application.
Unfortunately when using this function a few times it seems to run into a
memory leak.

I am using .net CF 2.0 (with C#) and the following:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Xml;
using System.Windows.Forms;
using OpenNETCF.Drawing.Imaging;

My images are loaded into an image array and I thought I can release them
from memory when loading images again into that array (some kind of overide -
but this is not the case, because it grows in memory)

Here's the code I use:

IImage[] image = new IImage[65];
ImagingFactory factory = new ImagingFactoryClass();

public void LoadImages()
{
...
factory.CreateImageFromStream(new StreamOnFile("Image1.png"), out
image[1]);
factory.CreateImageFromStream(new StreamOnFile("Image2.png"), out
image[2]);
factory.CreateImageFromStream(new StreamOnFile("Image3.png"), out
image[3]);
...
}

So when changing to another theme I reload my images with LoadImages() and
the memory usage grows every time with about 0.5MB

I would much appreciate any pointers you can give me.

Thanks!

juvi
 
J

Jesse Houwing

Hello juvi,
OS........: [CE 5.0 / WM5.0 / WM6.0]
Hardware..: [HTC TOUCH DIAMOND]
Processor.: [Qualcomm MSM7201A]
I am trying to implement a "change theme" functionality in my
application. Unfortunately when using this function a few times it
seems to run into a memory leak.

I am using .net CF 2.0 (with C#) and the following:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Xml;
using System.Windows.Forms;
using OpenNETCF.Drawing.Imaging;
My images are loaded into an image array and I thought I can release
them from memory when loading images again into that array (some kind
of overide - but this is not the case, because it grows in memory)

Here's the code I use:

IImage[] image = new IImage[65];
ImagingFactory factory = new ImagingFactoryClass();
public void LoadImages()
{
...
factory.CreateImageFromStream(new StreamOnFile("Image1.png"), out
image[1]);
factory.CreateImageFromStream(new StreamOnFile("Image2.png"), out
image[2]);
factory.CreateImageFromStream(new StreamOnFile("Image3.png"), out
image[3]);
...
}
So when changing to another theme I reload my images with LoadImages()
and the memory usage grows every time with about 0.5MB

I would much appreciate any pointers you can give me.

Not knowing the exact inetrface of IImage I'd guess that it's IDisposable,
so first fispose the original array (or copy the array, load the images and
dispose the old one:

foreach(IDisposable imageInstance in image)
{
imageInstance.Dispose();
}

Also my guess would be that StreamOnFile is IDisposable as well, so:

using (stream s = new StreamOnFile("image.png))
{
factory.CreateImageFromStream(s, out image[x]);
}

For that matter, why not make this code a whole lot easier to read:

string[] fileLocations = new string{"image1.png", "image2.png", "image3.png",
....}; // 65 locations
images[] = new IImage[65];

public void LoadImages()
{
for (i = 0; i < fileLocations .Length; i++)
{
if (images != null)
{
images.Dispose();
}
using (Stream s = new StreamOnFile(fileLocations ))
{
factory.CreateImageFromStream(s, out images);
}
}
}

This makes it easier to use ingeritance as well. Just override the fileLocations
array and you're done.
 
J

juvi

hello and thank you for your reply:

Unfortunately I am running into an InvalidCastExecption when trying this code:

foreach(IDisposable imageInstance in image)
{
imageInstance.Dispose();
}

And when I try the following then there is no Dispose() methode for images:

string[] fileLocations = new string{"image1.png", "image2.png", "image3.png",
.....}; // 65 locations
images[] = new IImage[65];

public void LoadImages()
{
for (i = 0; i < fileLocations .Length; i++)
{
if (images != null)
{
images.Dispose(); //this method is not available here
}
using (Stream s = new StreamOnFile(fileLocations ))
{
factory.CreateImageFromStream(s, out images);
}
}
}

Looking forward to your reply.
 
J

Jesse Houwing

Hello juvi,
hello and thank you for your reply:

Unfortunately I am running into an InvalidCastExecption when trying
this code:

foreach(IDisposable imageInstance in image)
{
imageInstance.Dispose();
}
And when I try the following then there is no Dispose() methode for
images:

string[] fileLocations = new string{"image1.png", "image2.png",
"image3.png",
....}; // 65 locations
images[] = new IImage[65];
public void LoadImages()
{
for (i = 0; i < fileLocations .Length; i++)
{
if (images != null)
{
images.Dispose(); //this method is not available here
}
using (Stream s = new StreamOnFile(fileLocations ))
{
factory.CreateImageFromStream(s, out images);
}
}
}
Looking forward to your reply.


It seems that IImage doesn't implement IDisposable, but that you need to
Dispose the underlying image nonetheless.

See http://www.pcreview.co.uk/forums/thread-2357463.php for more details.
 
J

Jesse Houwing

Hello juvi,
hello and thank you for your reply:

Unfortunately I am running into an InvalidCastExecption when trying
this code:

foreach(IDisposable imageInstance in image)
{
imageInstance.Dispose();
}
And when I try the following then there is no Dispose() methode for
images:

Changed the code below so that it should work:

string[] fileLocations = new string{"image1.png", "image2.png", "image3.png",
.....}; // 65 locations
images[] = new IImage[65];

public void LoadImages()
{
for (i = 0; i < fileLocations .Length; i++)
{
if (images != null && images.Image != null)
{
images.Image.Dispose();
}
using (Stream s = new StreamOnFile(fileLocations ))
{
factory.CreateImageFromStream(s, out images);
}
}
}
 
J

juvi

Unfortunately when trying to release the Com object with
Marshal.FinalReleaseComObject(image) I get an ArgumentException?
 
Top