Note that there are some explanatory texts on larger screens.

plurals
  1. POWhy doesn't FastBitmap get garbage collected?
    primarykey
    data
    text
    <p>So I've finally located a problem I have with growing memory consumption. It's the class below, which for some reason doesn't get garbage collected. What would be the problem? The idea of the FastBitmap class is to lock the bitmap data of a bitmap image once to avoid locking/unlocking on each call to GetPixel/SetPixel.</p> <pre><code> public unsafe class FastBitmap { private Bitmap subject; private int subject_width; private BitmapData bitmap_data = null; private Byte* p_base = null; public FastBitmap(Bitmap subject_bitmap) { this.subject = subject_bitmap; try { LockBitmap(); } catch (Exception ex) { throw ex; } } public void Release() { try { UnlockBitmap(); } catch (Exception ex) { throw ex; } } public Bitmap Bitmap { get { return subject; } } public void LockBitmap() { GraphicsUnit unit = GraphicsUnit.Pixel; RectangleF boundsF = subject.GetBounds(ref unit); Rectangle bounds = new Rectangle((int)boundsF.X, (int)boundsF.Y, (int)boundsF.Width, (int)boundsF.Height); subject_width = (int)boundsF.Width * sizeof(int); if (subject_width % 4 != 0) { subject_width = 4 * (subject_width / 4 + 1); } bitmap_data = subject.LockBits(bounds, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); p_base = (Byte*)bitmap_data.Scan0.ToPointer(); } private void UnlockBitmap() { if (bitmap_data == null) return; subject.UnlockBits(bitmap_data); bitmap_data = null; p_base = null; } } </code></pre> <p><strong>EDIT</strong></p> <p>Here's how it does get properly collected..</p> <pre><code>public unsafe class FastBitmap : IDisposable { private Bitmap subject; private int subject_width; private BitmapData bitmap_data = null; private Byte* p_base = null; public FastBitmap(Bitmap subject_bitmap) { this.subject = subject_bitmap; try { LockBitmap(); } catch (Exception ex) { throw ex; } } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } private bool disposed = false; protected virtual void Dispose(bool disposing) { if (!this.disposed) { if (disposing) { UnlockBitmap(); Bitmap.Dispose(); } subject = null; bitmap_data = null; p_base = null; disposed = true; } } ~FastBitmap() { Dispose(false); } public Bitmap Bitmap { get { return subject; } } public void LockBitmap() { GraphicsUnit unit = GraphicsUnit.Pixel; RectangleF boundsF = subject.GetBounds(ref unit); Rectangle bounds = new Rectangle((int)boundsF.X, (int)boundsF.Y, (int)boundsF.Width, (int)boundsF.Height); subject_width = (int)boundsF.Width * sizeof(int); if (subject_width % 4 != 0) { subject_width = 4 * (subject_width / 4 + 1); } bitmap_data = subject.LockBits(bounds, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); p_base = (Byte*)bitmap_data.Scan0.ToPointer(); } public void UnlockBitmap() { if (bitmap_data == null) return; subject.UnlockBits(bitmap_data); bitmap_data = null; p_base = null; } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload