当没有剩余内存时,.Net 和 Bitmap 不会被 GC 自动处理

2023-11-29

我想知道.NET 中为位图分配的内存的分配和处置是如何工作的。

当我在函数中的循环中创建大量位图并连续调用它时,它将一直工作,直到某个时候位图无法分配内存,给出指定大小的“无效参数”异常。

如果我在垃圾收集器工作时调用垃圾收集器。

使用以下代码,您可以重现该错误:

class BitmapObject {
    public bool Visible {
        get { return enb; }
        set { enb = value; }
    }
    private bool enb;
    private Bitmap bmp;
public BitmapObject(int i, bool en)
{
    enb = en;
    bmp = new Bitmap(i, i);


   }
}

class Pool<T> where T : BitmapObject
{
    List<T> preallocatedBitmaps = new List<T>();
public void Fill() {
    Random r = new Random();
    for (int i = 0; i < 500; i++) {
        BitmapObject item = new BitmapObject(500, r.NextDouble() > 0.5);
        preallocatedBitmaps.Add(item as T);
    }
}

public IEnumerable<T> Objects
{
    get
    {
        foreach (T component in this.preallocatedBitmaps)
        {
            if (component.Visible)
            {
                yield return (T)component;
            }
        }


     }
    }
}

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
{
    for (int i = 0; i < 10; i++ )
    {
        Test();

            // without this it breaks
            //GC.Collect();
            //GC.WaitForPendingFinalizers();
        }

        Console.ReadKey();
    }

    private static void Test() {
        Pool<BitmapObject> pool = new Pool<BitmapObject>();
        pool.Fill();

        for (int i = 0; i < 100; i++)
        {
            var visBitmaps = pool.Objects;
            // do something
        }       
     }
}

Bitmap 类不可避免地是您需要使用的类have停止忽略 IDisposable 的存在。它是一个围绕 GDI+ 对象的小包装类。 GDI+ 是非托管代码。位图占用非托管内存。位图很大时会很多。

.NET 垃圾收集器确保使用终结器线程释放非托管系统资源。问题是,只有当您创建足够数量的managed对象来触发垃圾收集。这对于 Bitmap 类来说效果不佳,您可以在垃圾收集堆的第 0 代填满之前创建数千个 Bitmap 类。在到达那里之前,您将耗尽非托管内存。

需要管理您使用的位图的生命周期。当您不再使用 Dispose() 方法时,请调用它。这并不总是最佳解决方案,如果您有太多实时位图,您可能必须重新考虑您的方法。 64 位操作系统是下一个解决方案。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

当没有剩余内存时,.Net 和 Bitmap 不会被 GC 自动处理 的相关文章

随机推荐

  • 我的 Android Studio 从 3.4 更新到 3.5 后不断崩溃

    从今天起我就一直面临这个问题 昨天我将 Android Studio 从 3 4 更新到 3 5 它运行良好 但从今天开始 它在启动时崩溃 当我启动时 它显示启动屏幕 然后尝试加载项目并突然关闭或崩溃 而不显示任何错误消息 我应该怎么办 是
  • Delphi XE4 - 八进制常数像十进制常数一样工作

    今天我正在对我的队友进行代码审查 它是普通的旧 Delphi 版本 XE4 我检测到这样的代码 cWin CountryIdsSet array 0 243 of integer 499 688 040 它是十进制 ID 列表 但其中之一
  • C- 使用位域时结构的大小以及它如何存储在内存中

    void main struct bitfield signed int a 3 unsigned int b 13 unsigned int c 1 struct bitfield bit1 2 14 1 clrscr printf d
  • C++ 子模式匹配

    谁能告诉我一个关于在 C C 中使用正则表达式 regex h 来搜索和 或提取正则表达式中的子模式的示例 在 javascript 中 它会是这样的 var str the string contains 123 dots and 344
  • While 循环,每个其他循环的语句?

    我有一个 while 循环 每个循环显示一个 li li 在列表中 有没有办法告诉 php 每个其他循环都应该回显 li style background 222 li 在我的 CSS 中 我将另一种颜色 111 设置为默认值 以便我的网站
  • 如何使用python通过beautifulsoup中的lxml从网页中提取img src?

    我是 python 新手 正在从事亚马逊的网页抓取项目 我在如何使用 BeautifulSoup 通过 lxml 从产品页面中提取产品 img src 时遇到问题 我尝试使用以下代码来提取它 但它没有显示 img 的 url 这是我的代码
  • eXist-db compression:zip 函数是否添加 XML 声明

    我有一个 XQuery 函数可以将一组 XML 文件转换为 HTML 并压缩它们 它在每个文件上运行一个 transform 来创建 元素 从该函数开始 declare function xport make sources path as
  • Spring:一个类可以同时是@Document和@Table吗

    我在 MVC 上下文中使用 spring 我正在使用 Cassandra 和 MonogDB 对于该项目 我必须使我的模型和 dao 类与这两个数据库兼容 是否可以有相同的模型类 Document并且也可以是 Table spring能在运
  • 全局添加函数到原型(从模块内)

    我想从模块内向 Typescript 1 8 中的数组原型添加一个函数 我正在更改 utils ts 文件中的原型 declare global interface Array
  • 将鼠标悬停在图像上时以受控方式滚动 div 内容

    我有一个高度和宽度有限的 div 其内容超出了 div 的大小 因此 我在 div 的顶部和底部放置了两个图像 并且我希望内容相对于我悬停在其上的图像上下滚动 我已经成功地实现了悬停 但它不受控制 即使我将鼠标移离图像 它也会一直持续到最后
  • 当会话被视为已访问时

    是否打电话HttpServletRequest getSession boolean create 导致会话的最后访问时间被更新 关于什么getId 方法甚至调用getLastaccessedtime 简而言之 访问的标准是什么 HttpS
  • 使用 CUSPARSE 时遇到问题

    当我想编译我的程序 使用 Cusparse 时 出现了以下几行 tmp tmpxft 00001048 00000000 13 matvec o 在函数中main tmpxft 00001048 00000000 1 matvec cuda
  • 如何在 Fortran 中抑制“已删除功能:暂停语句”的警告?

    我用谷歌搜索但找不到答案 我怎样才能抑制这个警告 并且只有这个 警告 删除的功能 1 处的 PAUSE 语句 我知道我可以抑制所有警告 但我只想抑制这一警告 或者如果不可能的话 抑制删除功能的警告 谢谢 A 使用 std legacy 或
  • 运行 Nuget 还原时出现 NU1202 错误

    我有一个 NET Framework 解决方案 正在尝试使用 Azure DevOps 上的管道进行设置 我在尝试恢复包时遇到错误 NU1202 Package AppCenter Analytics Metrics 1 1 0 is no
  • 如何在 Matplotlib 中选择 Y 轴上每个点之间的大小?

    我只是想使用 x 轴列表和 y 轴列表制作一个普通图表 但问题是 我希望能够选择 y 轴的大小 就像点之间的长度一样 我希望自己能够选择 例如 我的 y 轴叙述 0 2 5 5 7 5 等 我想将其更改为0 2 4 6 8 等 那么有没有办
  • Sql Server 2005 上的报告服务 2008

    我可以将 Reporting Services 2008 与 SQL Server 2005 数据库一起使用吗 我是否需要两个许可证 适用于 SQL Server 2008 和 SQL Server 2005 我是否需要两个实例 SQL S
  • 在java中编写哈希函数的最佳实践是什么?

    我想知道在 java 中编写 hashCode 方法的最佳实践是什么 可以找到很好的描述here 有那么好吗 这是引用自有效的Java第二版 第 9 项 始终覆盖hashCode当你覆盖equals 虽然本项中的配方产生了相当好的散列函数
  • Android通过firebase推送Notification(服务器端)

    我正在尝试使用 firebase 云消息传递系统从服务器向我的 Android 设备发送推送通知 我能够成功注册我的设备 并且也为我的设备生成了令牌 我无法使用以下脚本向我的设备发送通知
  • 使用 new 分配内存返回相同的内存地址

    class abc int x int main abc A new abc cout lt lt static cast
  • 当没有剩余内存时,.Net 和 Bitmap 不会被 GC 自动处理

    我想知道 NET 中为位图分配的内存的分配和处置是如何工作的 当我在函数中的循环中创建大量位图并连续调用它时 它将一直工作 直到某个时候位图无法分配内存 给出指定大小的 无效参数 异常 如果我在垃圾收集器工作时调用垃圾收集器 使用以下代码