[Mono-list] issue with pinvoke memory leak

2004-06-02 Thread Chris Turchin
hi,

i have the following sitution (not directly mono related but maybe interesting
regardless since a lot of pinvoke is going on here) that I do not know how to
handle cleanly:

i have been playing with  a wrapper for an image library with the following
method:

private static extern FIBITMAP FreeImage_Rescale(FIBITMAP dib, int dst_width,
int dst_height, FilterOption filter);

I had implemented it like this:

public FreeImage Resample(int newwidth, int newheight,
FilterOption filter)

which works fine with something like:

FreeImage img2 = img.Resample(100,100,FilterOption.BILINEAR);

but when I do:

img = img.Resample(100,100,FilterOption.BILINEAR);

then the img object is 'replaced' but a I have a big memory leak, since the
Dispose() method which handles the cleanup of unmanaged resources (the img
object has a pointer to the unmanaged image data which is normally released when
the object is disposed) is never called.

Can someone give me a tip how to handle this in a way that ensures that the old
data from img is disposed in the second case above? Actaully, would this same
issue be a problem for all IDisposable objects in managed code (maybe I am not
allowed to do this at all with IDisposable objects) or is this unique to the
managed/unmanaged code in question here?

Thanks for any feedback!

Regards,
--chris
___
Mono-list maillist  -  [EMAIL PROTECTED]
http://lists.ximian.com/mailman/listinfo/mono-list


Re: [Mono-list] issue with pinvoke memory leak

2004-06-02 Thread Chris Turchin

Hi Ravindra,

again, thanks for the tip. I checked and the finalizer  was there only it was
not getting called (or not often enough) - i added a GC.Collect() call to my
test class and it worked.

Thanks again!

Regards,

--chris

On Wed, 2 Jun 2004, Ravindra wrote:

 Hello,

 On Wed, 2004-06-02 at 17:00, Chris Turchin wrote:
  i have been playing with  a wrapper for an image library with the following
  method:
 
  private static extern FIBITMAP FreeImage_Rescale(FIBITMAP dib, int dst_width,
  int dst_height, FilterOption filter);
 
  I had implemented it like this:
 
  public FreeImage Resample(int newwidth, int newheight,
  FilterOption filter)
 
  which works fine with something like:
 
  FreeImage img2 = img.Resample(100,100,FilterOption.BILINEAR);
 
  but when I do:
 
  img = img.Resample(100,100,FilterOption.BILINEAR);
 
  then the img object is 'replaced' but a I have a big memory leak, since the
  Dispose() method which handles the cleanup of unmanaged resources (the img
  object has a pointer to the unmanaged image data which is normally released when
  the object is disposed) is never called.
 
  Can someone give me a tip how to handle this in a way that ensures that the old
  data from img is disposed in the second case above? Actaully, would this same
  issue be a problem for all IDisposable objects in managed code (maybe I am not
  allowed to do this at all with IDisposable objects) or is this unique to the
  managed/unmanaged code in question here?

 Dude, you need to implement finalizer for your FreeImage class.
 Finalizer method would do all the required cleanup you want to do. GC
 would call your class finalizer, when you are done with the referenced
 object.

 - Ravindra


___
Mono-list maillist  -  [EMAIL PROTECTED]
http://lists.ximian.com/mailman/listinfo/mono-list


Re: [Mono-list] issue with pinvoke memory leak

2004-06-02 Thread Jonathan Pryor
On Wed, 2004-06-02 at 08:09, Chris Turchin wrote:
 Hi Ravindra,
 
 again, thanks for the tip. I checked and the finalizer  was there only it was
 not getting called (or not often enough) - i added a GC.Collect() call to my
 test class and it worked.

Don't call GC.Collect().  Please.  Under .NET, manually calling
GC.Collect will throw off the algorithms that govern when .NET normally
collects memory, which can negatively impact performance.

Though relying on the finalizer will already impact performance, as
finalizers aren't run until after the object graph has been promoted a
generation.  For example, if it's a Generation 0 object that has a
finalizer and is collected, it's promoted to Generation 1 and the
finalizer isn't run until the *next* Generation 1 collection.  Which is
less frequent than Generation 0 collections.

If your object is promoted to Generation 2, it'll hang around awhile.

Result: you may have lots of unmanaged memory leaking, because it's
waiting for the collector to finalize the object...  (Imagine that you
have a 10 MB image opened in unmanaged memory and held open by a managed
handle.  It may be awhile before that memory is freed.)  Assuming, of
course, that the finalizer is *ever* executed, and there is no guarantee
that it will be.

In short, finalizers are nice as a fall back, but DO NOT rely on them. 
You have to remember to dispose of your resources in a timely basis.

Consequently, you should instead do:

FreeImage img = GetImage ();
FreeImage img2 = img.Resample (...);
img.Dispose ();
img = img2;

That's assuming that you really need to do the aliasing.  If you don't
need to keep re-using the img variable, you could use the using
block:

using (FreeImage img = GetMyImage()) {
using (FreeImage img2 = img.Resample (...)) {
// operate on img2
}
}

This will ensure that your unmanaged memory is freed in a timely manner.

Mono doesn't currently use a generational collector, so this currently
isn't as much of an issue.

snip/
   Actaully, would this same
   issue be a problem for all IDisposable objects in managed code (maybe I am not
   allowed to do this at all with IDisposable objects) or is this unique to the
   managed/unmanaged code in question here?

This is true for all IDisposable objects.  If the object doesn't have a
finalizer, then nothing will be invoked when the object is collected. 
Either invoke Dispose() directly, or use a using block so that Dispose()
is called for you.

This should be done for all resources -- unmanaged memory, database
locks, file handles, monitors... Everything that may be limited and
needs to be released in a timely manner to avoid performance issues.

Finalizers can help in freeing these resources, but they're no
guarantee.  Use them as a fall-back ONLY.

 - Jon


___
Mono-list maillist  -  [EMAIL PROTECTED]
http://lists.ximian.com/mailman/listinfo/mono-list