尝试加载150+灰度4096 x 4096位图.我想需要帮助来绕过2GB的限制

本文关键字:帮助 2GB 150+ 加载 灰度 4096 4096位图 | 更新日期: 2023-09-27 18:04:37

Solved:我错误地认为Visual Studio 2012在制作新项目时默认构建64位应用程序。在"解决方案属性,构建"选项卡下,有一个标记为"首选32位"的复选框。当我选中这个复选框并重新构建我的解决方案时,我能够一次加载和处理200多个位图。感谢Mike Trusov如此礼貌地为我指出解决方案。

原始问题:我遇到了一个小问题。我有超过150个灰度位图,我想加载到一个8gb系统的RAM中,但我似乎无法超过50个左右而不抛出异常。我试过将位图加载到数组中,当然这是徒劳的,因为。net有2GB的限制。但早在2GB的位图加载之前,它就失败了。所以我试着把它们装进List<List<Bitmap>>,但即使这样也会在相同的地方失败。在出现异常时,任务管理器显示有3939 MB的可用RAM等待填充。很奇怪。

我不需要这些位图在RAM中连续。它们可以是一堆分散的16 MB分配。我只想用一堆位图来填充可用的内存。就是这样。

异常在不同的时间是OutOfMemory异常或ArgumentException,这取决于我启动程序时有多少可用RAM。在这两种情况下,堆栈跟踪在System.Drawing.Bitmap..ctor(String filename)内终止。在异常发生时加载的特定文件没有任何问题。事实上,当我让它加载不同(甚至重叠)的位图集时,错误会在相同的迭代中发生。

有没有人有线索可以借给我如何做到这一点?我是否以某种奇怪的方式进入了。net 2GB限制?

回答一些问题和评论:我在一台8gb内存的电脑上使用Visual Studio 2012, . net 4.5, 64位Windows 7。是的,出于各种原因(性能,图像处理原因等),我需要同时在RAM中存储所有这些位图。我已经考虑使用gcAllowVeryLargeObjects,但我不需要或想要我所有的位图在一个长块的连续内存。我宁愿每个位图使用自己单独的内存分配。此外,如果我有一台64 GB RAM的机器,那么将其限制为150个这种大小的位图将是荒谬的。为什么这些位图加载时不抛出OutOfMemoryException?

对我来说,似乎。net试图保持所有位图在一个单独的2gb区域。如果有一种方法可以让每个位图(说的比我知道的更多)有自己单独的地址空间,那可能会解决这个问题。为了调用很久以前的MS-DOS语言,我想使用一个长指针来分配和访问远内存,而不是让我所有的数据都卡在一个近段中。

数组代码如下:

    List<String> imageFiles;            // List of .bmp filenames.
    Bitmap[] bmps = new Bitmap[100];    // Stores/accesses the Bitmaps.
    private void goButton_Click(object sender, EventArgs e)
    {
        int i;
        // Load the bitmaps
        if (bmps[0] == null)
        {
            // Load the list of bitmap files.
            imageFiles = Directory.EnumerateFiles(@"C:'Temp", "*.bmp", SearchOption.TopDirectoryOnly).ToList();
            // Read bitmap files
            for (i = 0; i < bmps.Length; ++i)
            {
                bmps[i] = new Bitmap(imageFiles[i]);    // <-- Exception occurs here when i == 52 or so.
            }
        }
    }

下面是List>代码:

    List<String> imageFiles;                                // List of .bmp filenames.
    List<List<Bitmap>> bmps = new List<List<Bitmap>>(100);  // Stores/accesses the Bitmaps.
    private void goButton_Click(object sender, EventArgs e)
    {
        int i;
        // Load the bitmaps
        if (bmps.Count == 0)
        {
            // Load the list of bitmap files.
            imageFiles = Directory.EnumerateFiles(@"C:'Temp", "*.bmp", SearchOption.TopDirectoryOnly).ToList();
            // Read bitmap files
            for (i = 0; i < 100; ++i)
            {
                // Load the bitmap into temporary Bitmap b.
                Bitmap b = new Bitmap(imageFiles[i]);   // <-- Exception occurs here when i == 52 or so.
                // Create and add a List<Bitmap> that will receive the clone of Bitmap b.
                bmps.Add(new List<Bitmap>(1));
                // Clone Bitmap b and add that cloned Bitmap to the Bitmap of List<Bitmap>.
                bmps[i].Add((Bitmap)b.Clone());
                // Dispose Bitmap b.
                b.Dispose();
            }
        }
    }

尝试加载150+灰度4096 x 4096位图.我想需要帮助来绕过2GB的限制

在64位应用程序中加载超过2gb的位图到内存中应该没有问题(检查项目设置-可能必须为任何基于x86的CPU创建一个新的配置)运行在64位操作系统上(我猜你是)。一个简单的列表也可以:

    var imageFiles = Directory.EnumerateFiles(@"C:'Temp", "*.bmp", SearchOption.TopDirectoryOnly).ToList();
    var lst = new List<Bitmap>();
    foreach (var imageFile in imageFiles)
    {
        lst.Add(new Bitmap(imageFile));
    }

它们所有必须同时加载吗?你能加载20个吗,然后当你处理或显示这些的时候,你有一个后台线程准备接下来的20个。