GDI+ on 64bit systems
Our system uses a lot of large Bitmaps (System.Drawing.Bitmap) and sometimes we run ou开发者_JAVA百科t of memory and gets a "Parameter is not valid" error. This makes sense, since it can be difficult to allocate large continuous chunk of memory.
So the question is... If we upgraded the system to 64bit, would this problem go away?
If this is a memory allocation problem (due to fragmentation of your large object heap it is quite conceivable that you would have trouble allocating 100MB chunks after 20 or so images have been loaded, even if some of them have subsequently been unloaded), then moving to 64 bit should help - the much larger address space should give the heap plenty of room to work, and thus alleviate the symptoms.
A memory issue should produce an OutOfMemoryException, but it's possible that the bitmap handling code in .net is catching this and effectively converting into an InvalidParameterException. However, there is a possibility that there is another issue relating to the size/format of the images, and it is genuinely an Invalid Parameter.
In general, when you start playing with huge bitmap in memory you always get this kind of issue. Best way to avoid this is to split your image in an array or something similar so you can create a grid.
From that point on, you only need/have to load on the screen what can be viewed which would save a lot of memory.
I had this happen to me when I decided to create a little games to kill some times.
I decided to create a Maze/Pipe game and the user could choose the number of columns and rows. I decided to limit the image to 10000px by 10000px.
My first try, I had exactly your issue. error after error after error, mostly memory issue.
I decided to do some research on how to do what I wanted and I found the solution.
What I did is I created a dynamic 2d array (I decided to limit it to a maximum of 1000 by 1000) and I just put in them small 10x10 pixel image or whatever the user decide.
When that was done, the issue with memory/loading speed/etc... was simply gone.
memory usage before my fix was easily over a gig, now memory usage of the apps is between 150 and 225 megs ram when you use the limit
if you want to try it, download this and go look in the menu(Maze) and play with the setting: my little games
Depending on how the Bitmap is created, whether it is DDB or a DIB video memory or system memory is used (DDB's use video memory, DIB's system memory). You'll have to use DotNet reflector to determine when each one is created depending on the constructor you are using... For example a DDB is created when you go:
var bmp = new Bitmap(width, height, pixelDepth)
and this can have a size limit of 5000x5000 on a machine with a small video card (i.e. servers where you might be running a webservice), whereas you can find that you can load a 10000x10000 bitmap with
var bmp = new Bitmap(pathToLargeFilename);
I haven't had much luck figuring out how to force creation of DIB in Dotnet (my guess is the easiest way would be manual creation of the Bitmap stucture, manual allocation of the memory, and then somehow casting that as a Bitmap. Or maybe your best bet is to move to an alternate imaging library that doesn't use video memory (there are a quite a few open source ones FreeImage, ImageMagick, Cairo (though you will have to at least get the GTK packages from Mono for it to run)
Some time ago I often experienced exactly this kind of errors when developing with Visual Studio 2008 on a Vista 64-Bit system. So I guess moving to 64Bit may increase the chances to succeed and make the error occur less often, but I would not assume that moving to 64-Bit will heal it entirely.
What helped me out was this link: http://confluence.jetbrains.net/display/ReSharper/OutOfMemoryException+Fix
It is a wrapper that replaces the memory allocation policy, s.t. you tend to get larger continuous memory chunks. Maybe you can use a similar memory allocation policy in your application as well, because this one was supposed to wrap visual studio only.
There is a limit as to how large a bitmap you can create on e a system.
Check out http://www.efg2.com/Lab/Graphics/VeryLargeBitmap.htm for a program that can show you the system limit.
Perhaps you are hitting that limit.
Before allocating these big Bitmaps, you could try calling GC.Collect(). I had exactly this problem recently, and that helped. (My first reaction was also to move to 64-bit, but adding one line of code was a little bit simpler. ;-)
精彩评论