gpt4 book ai didi

c# - 为什么 FastBitmap 没有被垃圾回收?

转载 作者:行者123 更新时间:2023-12-01 23:16:38 26 4
gpt4 key购买 nike

所以我终于找到了内存消耗不断增加的问题。这是下面的类,由于某种原因没有被垃圾收集。会有什么问题呢?FastBitmap 类的想法是锁定位图图像的位图数据一次,以避免每次调用 GetPixel/SetPixel 时锁定/解锁。

    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;
}
}

编辑

以下是如何正确收集它的方法..

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;
}
}

最佳答案

几点:

  • 您的类(class)拥有对固定数据的访问权限。垃圾收集器通过在内存中移动结构来工作。只要位图锁定了其位,垃圾收集器就无法对其执行任何操作。

  • 一旦您发布了 FastBitmap,恐怕 GDI+ 可能仍会卡在数据位上。 GDI+ 是一个 native 库,不与垃圾收集器交互。

  • 您还需要释放(处置)GDI+ 位图。只需在 Release 中调用 subject.Dispose() 即可。

正如 Mitchel 提到的,最好让 FastBitmap 实现 IDisposable 并重命名 Release 进行处置。这将允许您在代码中使用 using 语句来确保确定地释放数据。

关于c# - 为什么 FastBitmap 没有被垃圾回收?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1790678/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com