c# - 在 c# 中加载 1000 张图像而不会出现内存不足异常

标签 c# image memory-leaks out-of-memory

我想在桌面应用程序的运行时在面板中添加 1000 个图像(每个大小为 (40 到 100) KB)。首先,用户浏览所有图像并将它们加载到面板上。当它一个接一个地加载图像时,任务管理器中显示的内存使用量会迅速增加,并且在一定数量的图像后会显示“内存不足异常”。我的代码哪里出了问题?

在加载 700 张图像之前,任务管理器显示 1.05 GB 内存使用情况。 加载任务管理器后显示 2.04 GB 和 2 GB RAM 溢出

int picnumber = 0;
        int numberOfImages = 12;

        numberOfImages = Convert.ToInt32(textBox1.Text.ToString());

        for (int i = 0; i < numberOfImages; i++)
        {
            GroupBox gBox = new GroupBox();

            picnumber++;


            ////////////////////////////////

            // calculate the position of the groupbox where it is placed.
            if ((picnumber % 3) == 1)
            {
                x = initX;
            }
            else
            {
                if ((picnumber % 3) == 0)
                {
                    x = initX + 2 * (130 + 20);
                }
                else
                {
                    x = initX + 130 + 20;
                }

            }
            ///////////////////////////////////


            System.Drawing.Point CurrentPoint;

            CurrentPoint = panel1.AutoScrollPosition;
            y = initY + ((picnumber - 1) / 3) * (130 + 20) - (Math.Abs(panel1.AutoScrollPosition.Y));

            gBox.Text = picnumber.ToString();

            //place the groupbox in the appropriate position.
            gBox.Location = new System.Drawing.Point(x, y);
            gBox.Size = new System.Drawing.Size(130, 130);

            Bitmap btmap = new Bitmap(@"E:\43.jpg");
            // attach the image to the groupbox
            gBox.BackgroundImage = btmap;
            **gBox.BackgroundImageLayout = ImageLayout.Stretch;
            // add the groupbox that contains image to the panel.
            panel1.Controls.Add(gBox);**

但我看到一些应用程序可以加载大量图像并且占用的内存可以忽略不计,例如“Batch Image Resizer”( http://www.jklnsoft.com/ )

应用程序如何处理内存?它们遵循什么机制?

在加载 700 张图像之前,任务管理器显示 1.05 GB 内存使用量。 加载任务管理器后显示 1.06 GB

开发环境: C#.net 框架 4, window , Visual Studio 2010, 内存:2GB

最佳答案

重要的是要注意,100kb 的 JPG 占用的内存比仅仅 100kb 多很多。 100KB 是磁盘上数据的压缩大小。如果你有一张 800x600 的 32 位(这意味着每像素图像信息 4 个字节)图像,它在磁盘上可能是 100kb,但是你解压缩它并将它存储在内存中以便能够显示它,那就是 800 * 600 * 4 = 1,920,000 字节 = 1.83 MB RAM。 1.83 * 700 = 1,281 MB RAM 用于保存所有这些图像。

解决方案是加载图像并在内存中创建它的较小缩略图,然后从内存中丢弃原始图像。如果您的 800x600 有一个 80x60@16 位的缩略图,那么显示它只需要 9.3kb 的 RAM。其中 700 个只会消耗 6.5MB 的 RAM - 一个巨大的差异!

关于c# - 在 c# 中加载 1000 张图像而不会出现内存不足异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8982699/

相关文章:

c# - 创建非事件 C# WPF 窗口的缩略图

c# - 如何将 List<List<string>> 转换为 DataTable

c# - 无法将当前 JSON 对象(例如 {"name":"value"})反序列化为类型 'System.Collections.Generic.List` 1

java - 有条件的拖放图像

c++ - 返回指针(数组)时可能发生内存泄漏 (C++)

c# - 单个 View 中的多个模型 (C# MVC3)

javascript - 如何阻止 iPhone 在上传到后端时重新压缩图像?

jQuery 使用淡入淡出效果更改图像 src

c++ - 如何合并同一进程多次运行的 Valgrind memcheck 报告?

iphone - 将 UIImage 的区域分配给 UIImageView animationImages 时发生泄漏