Answered by:
Out of memory exceptions in c# 4.0

Question
-
For some days I have been trying to optimize an image processing program (cropping, rotate, changing brightness and undo) written in c# 4.0. Getting suggestions from google I have optimized the code in many ways. At first some disposable objects hadn’t been disposed that’s why exception was shown. But I have tried to dispose all disposable objects. Still the program is showing out of memory exceptions. That’s why I have uploaded the program for better solutions. Please download from the link
http://www.box.com/s/8eab0f3669ec4d79e3fc
My machine configuration: Core 2 Duo, 2 GB RAM, Windows XP service pack 3
Follow the steps:
Run the program
Load multiple images (at least 6) (each image is 3.5 MB or greater)
Double click on an image, crop (right click) and save. Do the same operation for other images. See what happens. It will show out of memory exceptions.
If any other operations (e.g. changing brightness) is done repeatedly (again and again) then it also shows out of memory exception.
I am eagerly waiting for your reply.
Monday, April 23, 2012 2:24 PM
Answers
-
Hi,
I tried to build the app as both x64 and x86, loaded 50 big images, then tried to crop some of the images and saved them. However, I cannot repro the OutOfMemoryException again. I also have a quick review of your codes and I think the Dispose method is used appropriately. Since now I cannot repro the issue, so it's hard to dig more deeply.
Besides, I believe the OutOfMemoryException can be caused if we crop outside area of the image, which is also discussed here, http://stackoverflow.com/questions/199468/c-sharp-image-clone-out-of-memory-exception
Good day!
Thanks
Michael Sun [MSFT]
MSDN Community Support | Feedback to us
- Proposed as answer by Michael Sun [MSFT]Microsoft employee Tuesday, May 29, 2012 2:17 AM
- Marked as answer by Mike Dos Zhang Tuesday, May 29, 2012 6:12 AM
Tuesday, May 15, 2012 2:53 AM -
Hi,
Thanks for the update! Croping all the images and save them may take some time. :) However, I think if the exception is only thrown in such a condition, the problem could be short of memory. Did you try build the app as x64 and execute it in x64 systems? Besides, I would recommend you use some memory tools like Performance Counter and VMMap to see the real memory usage of the app.
http://msdn.microsoft.com/en-us/magazine/cc163528.aspx
http://technet.microsoft.com/en-us/sysinternals/dd535533
Good day!
Thanks
Michael Sun [MSFT]
MSDN Community Support | Feedback to us
- Proposed as answer by Michael Sun [MSFT]Microsoft employee Tuesday, May 22, 2012 1:53 AM
- Marked as answer by Mike Dos Zhang Tuesday, May 29, 2012 6:12 AM
Thursday, May 17, 2012 6:10 AM
All replies
-
Hi,
We are doing research on this issue, if we get anything, we will let you know.
Best Regards,
Bob Wu [MSFT]
MSDN Community Support | Feedback to us
Thursday, April 26, 2012 9:23 AM -
Hi,
Welcome to MSDN forum!
Based on my test, I think the exception is thrown because part of the crop function userRect square is outside of the PictureBox image square. Please make sure the crop square cannot outside the image square.
Have a nice weekend!
Thanks
Michael Sun [MSFT]
MSDN Community Support | Feedback to us
Friday, April 27, 2012 4:55 PM -
Thanks Michael for your suggestions.
I did as you suggested but the same problem happened again.
you can also test by replacing the cropImage() method in the frmImageProcessing.cs file.
private void cropImage()
{
xRatio = (float)picBoxImageProcessing.Image.Width / (float)picBoxImageProcessing.Width;
yRatio = (float)picBoxImageProcessing.Image.Height / (float)picBoxImageProcessing.Height;
userRect.rect.X = (int)(userRect.rect.X * xRatio);
userRect.rect.Y = (int)(userRect.rect.Y * yRatio);
userRect.rect.Width = (int)(userRect.rect.Width * xRatio);
userRect.rect.Height = (int)(userRect.rect.Height * yRatio);
//picBoxImageProcessing.Image.Dispose();
picBoxImageProcessing.Image = objImageProcessingHandler.cropImageCustom(userRect.rect); ;
userRect.rect.X = 10;
userRect.rect.Y = 10;
userRect.rect.Width = 100;
userRect.rect.Height = 100;
}
Sunday, April 29, 2012 9:05 AM -
Hi,
In the ImageProcessingHandler.cs file, I found
public Bitmap cropImageCustom(Rectangle cropArea)
{
objCurrImageHandler.RestorePrevious();
using (Bitmap bmpImage = new Bitmap(objCurrImageHandler.CurrentBitmap))
{Bitmap bmpCrop = bmpImage.Clone(cropArea, bmpImage.PixelFormat);
objCurrImageHandler.CurrentBitmap.Dispose();
objCurrImageHandler.CurrentBitmap = new Bitmap(bmpCrop);
bmpCrop.Dispose();
}return objCurrImageHandler.CurrentBitmap;
}The bmpImage's size will be the one we corp. However, when the second time we corp it, the bmpImage become width 100 and height 100. Then if we corp it again, it will throw the OutOfMemory exception.
My understanding is that even we corp the image, the bmpImage size should be still the same as the PictureBox's size (1000, 1333). picboxImageProcessing.Image does not equal to the bmpImage?
Good day!
Thanks
Michael Sun [MSFT]
MSDN Community Support | Feedback to us
- Proposed as answer by Michael Sun [MSFT]Microsoft employee Wednesday, May 2, 2012 1:39 AM
- Unproposed as answer by Michael Sun [MSFT]Microsoft employee Tuesday, May 29, 2012 2:17 AM
Monday, April 30, 2012 6:54 AM -
Hi,
Any update of this issue?
Have a nice weekend!
Thanks
Michael Sun [MSFT]
MSDN Community Support | Feedback to us
Friday, May 4, 2012 6:16 AM -
sorry. I couldn't solve it.
I may not understand what you said. But i tried to resize the picturebox with the same size of bmpImage, and it didn't solve the problem.
looking forward to hearing you.
Monday, May 7, 2012 4:07 AM -
Hi,
I tried to explain the issue better. :)
1. Please still use the following codes in the cropImage method of the frmImageProcessing.cs file.
private void cropImage() { xRatio = (float)picBoxImageProcessing.Image.Width / (float)picBoxImageProcessing.Width; yRatio = (float)picBoxImageProcessing.Image.Height / (float)picBoxImageProcessing.Height; userRect.rect.X = (int)(userRect.rect.X * xRatio); userRect.rect.Y = (int)(userRect.rect.Y * yRatio); userRect.rect.Width = (int)(userRect.rect.Width * xRatio); userRect.rect.Height = (int)(userRect.rect.Height * yRatio); picBoxImageProcessing.Image = objImageProcessingHandler.cropImageCustom(userRect.rect); ; }
2. Please crop the image by rect.X = 10, rect.Y = 10, rect.Width = 100 and rect.Height = 100.
3. Please crop the image by rect.X = 1, rect.Y = 1, rect.Width = 20 and rect.Height = 20.
Then no error will be thrown. However, in the step 3 if we crop the image by rect.X = 1, rect.Y = 1, rect.Width = 100 and rect.Height = 100, we will get the error. I believe the only difference is that square we tried to crop this time is larger than the image size (width 100, height 100).
So please make sure the image's size is expanded to the picture box size each time we crop it. Also, please make sure the square in the image where we crop is smaller than the image (my first post has mentioned this situation).
Good day!
Thanks
Michael Sun [MSFT]
MSDN Community Support | Feedback to us
Monday, May 7, 2012 12:21 PM -
I've got your point. I'll try and let you know.
Tuesday, May 8, 2012 8:15 AM -
Following the steps as you mentioned I got the exceptions, since the image width and height was 20 but the crop selection area was 100. that is the crop selection area is greater than image size. if it's that you have explained then I have to say something.
I have modified the method as follows:
private void cropImage()
{
xRatio = (float)picBoxImageProcessing.Image.Width / (float)picBoxImageProcessing.Width;
yRatio = (float)picBoxImageProcessing.Image.Height / (float)picBoxImageProcessing.Height;
// userRect.rect.X = (int)(userRect.rect.X * xRatio);
//userRect.rect.Y = (int)(userRect.rect.Y * yRatio);
//userRect.rect.Width = (int)(userRect.rect.Width * xRatio);
//userRect.rect.Height = (int)(userRect.rect.Height * yRatio);
Rectangle rectCropArea = new Rectangle();
rectCropArea.X = (int)(userRect.rect.X * xRatio);
rectCropArea.Y = (int)(userRect.rect.Y * yRatio);
rectCropArea.Width = (int)(userRect.rect.Width * xRatio);
rectCropArea.Height = (int)(userRect.rect.Height * yRatio);
//picBoxImageProcessing.Image.Dispose();
picBoxImageProcessing.Image = objImageProcessingHandler.cropImageCustom(rectCropArea);
}Running the code again I observed that though the image size is greater than the crop selection area but still it shows the exceptions.
In the ImageProcessingHandler.cs file, the bold line shows the exception.
public Bitmap cropImageCustom(Rectangle cropArea)
{
objCurrImageHandler.RestorePrevious();
// Here cropArea's width and height is less than objCurrImageHandler.CurrentBitmap's width and height
using (Bitmap bmpImage = new Bitmap(objCurrImageHandler.CurrentBitmap)) /// this line shows the exception
{Bitmap bmpCrop = bmpImage.Clone(cropArea, bmpImage.PixelFormat);
objCurrImageHandler.CurrentBitmap.Dispose();
objCurrImageHandler.CurrentBitmap = new Bitmap(bmpCrop);
bmpCrop.Dispose();
}return objCurrImageHandler.CurrentBitmap;
}Waiting for your feedback.
Thank you.
Tuesday, May 8, 2012 2:03 PM -
Hi,
However, based on my test if the crop size is smaller than the image size, the app works fine at my side. It's quite strange. Could you please let me know the steps to repro the issue based on your test?
Good day!
Thanks
Michael Sun [MSFT]
MSDN Community Support | Feedback to us
Tuesday, May 8, 2012 3:13 PM -
The app doesn't work for some images( greater than 3.5 MB and 5100 x 6540 resolution) that I have loaded but it works for other images(if not more than 50 images are loaded simultaneously). May be the problem for those specific images but I am not sure. Now I want to talk about the images on that the app works fine.
If many images are loaded (I loaded 50 images on test) and crop and save images one after another then memory usage gradually increases and shows Out of memory exception.
Follow the steps:
- Run the program
- Load multiple images simultaneously (at least 50) (each image is 3.5 MB or greater)
- Double click on an image, crop (right click) and save. Do the same operation for other images. See what happens and observe memory performance at task manager.
You will see gradual increment of memory usage in the task manager, although all objects has been disposed. Finally the app showed out of memory exceptions at my side.
Thanks.
- Edited by learnerlearner Wednesday, May 9, 2012 5:45 PM
Wednesday, May 9, 2012 5:37 PM -
For some days I have been trying to optimize an image processing program (cropping, rotate, changing brightness and undo) written in c# 4.0. Getting suggestions from google I have optimized the code in many ways. At first some disposable objects hadn’t been disposed that’s why exception was shown. But I have tried to dispose all disposable objects. Still the program is showing out of memory exceptions. That’s why I have uploaded the program for better solutions. Please download from the link
http://www.box.com/s/8eab0f3669ec4d79e3fc
My machine configuration: Core 2 Duo, 2 GB RAM, Windows XP service pack 3
Follow the steps:
Run the program
Load multiple images (at least 6) (each image is 3.5 MB or greater)
Double click on an image, crop (right click) and save. Do the same operation for other images. See what happens. It will show out of memory exceptions.
If any other operations (e.g. changing brightness) is done repeatedly (again and again) then it also shows out of memory exception.
I am eagerly waiting for your reply.
Is this a 64-bit app or 32-bit? try building it as 64-bit and see if this alters its behaviour...
Cap'n
Wednesday, May 9, 2012 8:56 PM -
I'll try to run the app in 64 bit machine. But I have to run the app in 32 bit machine as per client's requirement.
In the 32 bit machine photoshop can process huge amount of images without any exceptions. If photoshop can why my app can't?
Sunday, May 13, 2012 5:57 AM -
Hi,
I tried to build the app as both x64 and x86, loaded 50 big images, then tried to crop some of the images and saved them. However, I cannot repro the OutOfMemoryException again. I also have a quick review of your codes and I think the Dispose method is used appropriately. Since now I cannot repro the issue, so it's hard to dig more deeply.
Besides, I believe the OutOfMemoryException can be caused if we crop outside area of the image, which is also discussed here, http://stackoverflow.com/questions/199468/c-sharp-image-clone-out-of-memory-exception
Good day!
Thanks
Michael Sun [MSFT]
MSDN Community Support | Feedback to us
- Proposed as answer by Michael Sun [MSFT]Microsoft employee Tuesday, May 29, 2012 2:17 AM
- Marked as answer by Mike Dos Zhang Tuesday, May 29, 2012 6:12 AM
Tuesday, May 15, 2012 2:53 AM -
Thank you Michael for your continuous support.
You tried to crop some of the images and saved them. But I tried to crop all of the images and it showed the exception. It didn't show exception when not more than 50 images are cropped and saved. You can try again to crop and save all of the loaded images.
Thanks again.
- Edited by learnerlearner Wednesday, May 16, 2012 11:12 AM
Wednesday, May 16, 2012 11:08 AM -
Hi,
Thanks for the update! Croping all the images and save them may take some time. :) However, I think if the exception is only thrown in such a condition, the problem could be short of memory. Did you try build the app as x64 and execute it in x64 systems? Besides, I would recommend you use some memory tools like Performance Counter and VMMap to see the real memory usage of the app.
http://msdn.microsoft.com/en-us/magazine/cc163528.aspx
http://technet.microsoft.com/en-us/sysinternals/dd535533
Good day!
Thanks
Michael Sun [MSFT]
MSDN Community Support | Feedback to us
- Proposed as answer by Michael Sun [MSFT]Microsoft employee Tuesday, May 22, 2012 1:53 AM
- Marked as answer by Mike Dos Zhang Tuesday, May 29, 2012 6:12 AM
Thursday, May 17, 2012 6:10 AM