2010-04-16 74 views
0

我们的系统使用了很多大型Bitmaps(System.Drawing.Bitmap),有时我们耗尽内存并获取“Parameter is not valid”错误。这很有意义,因为分配大量连续的内存很困难。64位系统上的GDI +

所以问题是......如果我们将系统升级到64位,这个问题会消失吗?

+0

我们在说多大?还有,你确定“参数无效”错误是由于内存不足造成的吗? – 2010-04-16 06:22:59

+0

你好musicfreak。位图很容易就是5000x5000。一个沙盒应用程序,所以我最好的猜测是内存问题 – LaZe 2010-04-16 06:34:10

+0

你能告诉我们为什么这是一个C#的问题吗?你只是在一些查看器应用程序中打开位图,或者你是否开发位图代码或打开位图studio ...? – 2010-04-16 06:42:25

回答

3

如果这是一个内存分配问题(由于您的大对象堆的碎片这是很可以想象,20个左右的图片已经被加载后,你会遇到麻烦分配100MB块,即使他们中的一些,但是后来被卸载),然后移动到64位应该有所帮助 - 更大的地址空间应该有足够的工作空间,从而缓解症状。

内存问题应该会产生一个OutOfMemoryException,但是.net中的位图处理代码可能会捕获这个问题并有效转换为InvalidParameterException。但是,有可能存在与图像的大小/格式有关的另一个问题,并且它确实是无效参数。

+1

I ju st testet在64位系统上,并能够创建每个20000x20000像素的6个位图。 (大约1.5GB的图像)这在32位系统上是远远不可能的。 – LaZe 2010-04-16 19:55:02

0

前一段时间,我经常在Vista 64位系统上使用Visual Studio 2008进行开发时遇到这种错误。所以我想移动到64位可能会增加成功的机会,并使错误发生的次数减少,但我不会认为移动到64位将完全治愈它。

什么帮我走出了这个链接: http://confluence.jetbrains.net/display/ReSharper/OutOfMemoryException+Fix

它是替换内存分配政策的包装,S.T.你往往会获得更大的连续内存块。也许你也可以在你的应用程序中使用类似的内存分配策略,因为这个应该只包装visual studio。

0

在分配这些大的位图之前,您可以尝试调用GC.Collect()。我最近遇到了这个问题,这对我有帮助。 (我的第一反应也是移动到64位,但添加一行代码稍微简单一些;-)

+0

嗨,我真的这样做了,它确实有帮助......但问题无论如何都回来了。 – LaZe 2010-04-17 07:15:44

1

一般来说,当你开始在内存中使用巨大的位图进行播放时,你总是会得到这种类型的问题。避免这种情况的最佳方法是将图像分成数组或类似的东西,以便创建网格。

从这一点开始,您只需要/必须在屏幕上加载可以查看的内容,从而节省大量内存。

当我决定创建一个小游戏来杀一些时,我曾遇到过这种情况。

我决定创建一个迷宫/管道游戏,用户可以选择列数和行数。我决定将图像限制为10000px×10000px。

我的第一次尝试,我有你的问题。错误发生后错误,主要是内存问题。

我决定做一些研究,如何做我想要的,我找到了解决方案。我所做的是我创建了一个动态二维数组(我决定将其限制为最大1000),并且我只在其中放入了10x10像素的小图像或任何用户决定的内容。

完成后,内存/加载速度/ etc等问题就消失了。

内存使用我的修补程序是很容易在演出之前,现在的应用程序的内存占用兆150和225之间的RAM,当您使用限制

,如果你想尝试一下,下载这一点,去看看在菜单(迷宫)和播放设置:my little games

1

根据创建位图的方式,是DDB还是使用DIB视频内存或系统内存(DDB使用视频内存,DIB的系统内存)。你将不得不使用DotNet reflector取决于你使用的创建DDB构造...例如,确定当创建每一个当你去:

var bmp = new Bitmap(width, height, pixelDepth) 

,这可能具有5000x5000的大小限制用小显卡的机器上,而你可以发现你可以加载一个10000x10000位图

var bmp = new Bitmap(pathToLargeFilename); 

我没有多少运气搞清楚如何(在这里您可能正在运行一个Web服务,即服务器)强制创建DIB in Dotnet(我的猜测是最简单的方法是手动创建Bitmap结构,手动分配内存,然后以某种方式将其转换为位图。或者,也许你最好的选择是转移到另一个不使用视频内存的图像库(有很多开源的图像库FreeImage,ImageMagick,Cairo(尽管你必须至少从Mono获得GTK packages)要运行)

+0

感谢您的提示。它似乎使用GdipCreateBitmapFromScan0,所以我猜它使用系统内存。 – LaZe 2010-04-19 15:07:10

+0

这是从以前的位图(Scan0)创建位图,所以不管该位图是在哪里分配内存。 – 2010-04-19 19:21:51