using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
namespace TrainSVM
{
class Program
{
static void Main(string[] args)
{
FileStream fs = new FileStream("dg.train",FileMode.OpenOrCreate,FileAccess.Write);
StreamWriter sw = new StreamWriter(fs);
String[] filePathArr = Directory.GetFiles("E:\\images\\");
foreach (string filePath in filePathArr)
{
if (filePath.Contains("HBP"))
{
sw.Write("1 ");
Console.Write("1 ");
}
else
{
sw.Write("1 ");
Console.Write("1 ");
}
using (Bitmap originalBMP = new Bitmap(filePath))
{
/***********************/
Bitmap imageBody;
ImageBody.ImageBody im = new ImageBody.ImageBody(originalBMP);
using (imageBody = im.GetImageBody(-1))
{
/* white coat */
Bitmap whiteCoatBitmap = Rgb2Hsi.Rgb2Hsi.GetHuePlane(imageBody);
float WhiteCoatPixelPercentage = Rgb2Hsi.Rgb2Hsi.GetWhiteCoatPixelPercentage(whiteCoatBitmap);
//Console.Write("whiteDone\t");
sw.Write("1:" + WhiteCoatPixelPercentage + " ");
Console.Write("1:" + WhiteCoatPixelPercentage + " ");
/******************/
Quaternion.Quaternion qtr = new Quaternion.Quaternion(-15);
Bitmap yellowCoatBMP = qtr.processImage(imageBody);
//yellowCoatBMP.Save("yellowCoat.bmp");
float yellowCoatPixelPercentage = qtr.GetYellowCoatPixelPercentage(yellowCoatBMP);
//Console.Write("yellowCoatDone\t");
sw.Write("2:" + yellowCoatPixelPercentage + " ");
Console.Write("2:" + yellowCoatPixelPercentage + " ");
/**********************/
Bitmap balckPatchBitmap = BlackPatchDetection.BlackPatchDetector.MarkBlackPatches(imageBody);
float BlackPatchPixelPercentage = BlackPatchDetection.BlackPatchDetector.BlackPatchPercentage;
//Console.Write("balckPatchDone\n");
sw.Write("3:" + BlackPatchPixelPercentage + "\n");
Console.Write("3:" + BlackPatchPixelPercentage + "\n");
}
}
sw.Flush();
}
sw.Dispose();
fs.Dispose();
}
}
}

- 39
- 3
-
updated code with `using` block. Still OUTOFMEMORY. – imageWorker Apr 01 '10 at 11:19
-
1What's the `ImageBody` class? Can you post code for that? – Dan Puzey Apr 01 '10 at 11:25
-
nothing. It just has few integer parameters parameters. – imageWorker Apr 01 '10 at 11:28
-
2@imageWorker - the using statements you added will help, but you still aren't disposing `whiteCoatBitmap`, `yellowCoatBMP` and `balckPatchBitmap` (spelling copied from code). – Mike Two Apr 01 '10 at 11:35
-
Have you got the stack trace? – Mesh Apr 01 '10 at 11:36
-
@imageWorker: you say "nothing", but you're passing the image in to it. What's it doing with the image? – Dan Puzey Apr 01 '10 at 11:39
-
Silly question, but how big does the dg.train file get? – Steve Syfuhs Apr 01 '10 at 16:57
-
~600Bytes. that is it has around 20 lines. – imageWorker Apr 01 '10 at 18:50
8 Answers
There are some Bitmap instances there that you aren't disposing. You should really try to get in the habit of using a using
block rather than disposing manually, to stop these things slipping through the net.

- 71,481
- 13
- 158
- 186
-
1Indeed, using-blocks add a try-finally for you as well (as you certainly know) which his code lacks. – Skurmedel Apr 01 '10 at 11:02
-
1Why a try-finally? If all the disposables are in using blocks these guarantee the Dispose call without needine one. – David M Apr 01 '10 at 11:09
-
I think you misunderstood me, that's one of the things you get from the using-statement. I didn't mean that you need try-finally with using-blocks, I mean that you won't need try-finally with using-blocks. :) – Skurmedel Apr 01 '10 at 11:14
-
-
If you're getting the exception on this line:
using (Bitmap originalBMP = new Bitmap(filePath))
then that may mean you're trying to load an invalid or corrupted image file. For reasons known to no man, the OutOfMemoryException
is what's thrown in this case. It actually has nothing to do with really being out of memory.
Try googling "bitmap.fromfile outofmemoryexception".

- 74,184
- 40
- 190
- 334
-
1
-
@Mike: it's extra-bad in this case, because image files tend to be some of the largest objects you deal with in .Net, so when you run into an `OutOfMemoryException`, it's easy to assume that you're really, you know, *out of memory*. – MusiGenesis Apr 01 '10 at 11:49
Shouldn't you be disposing imageBody
as well?
I see it's opened:
Bitmap imageBody;
ImageBody.ImageBody im = new ImageBody.ImageBody(originalBMP);
imageBody = im.GetImageBody(-1);
But I don't see you disposing of it / setting it to null?

- 6,680
- 13
- 43
- 71
-
+1. Certainly he should, huge images lying undisposed can never be good. – Skurmedel Apr 01 '10 at 10:59
-
Disposing it and setting it to null are two completely different things (although I suspect you probably know that already). – LukeH Apr 01 '10 at 11:00
-
I added it. and again running my code. I'm still getting this error. – imageWorker Apr 01 '10 at 11:02
-
What did you add? Can you update your original post to reflect your changes? – AndrewC Apr 01 '10 at 11:03
-
btw.. I'm declaring these variables in side the `foreach` loop block. So doesn't that mean in each loop iteration. The previous object reference is destroyed and object should be collected by GC? – imageWorker Apr 01 '10 at 11:09
-
Yes and no, imageWorker: GC will collect them, but it won't necessarily happen straight away. – Dan Puzey Apr 01 '10 at 11:27
-
2Also: why are people suggesting he dispose of this ImageBody class with no idea of what it actually does? If the image is passed in, there's no obvious reason that the class should even be disposable. – Dan Puzey Apr 01 '10 at 11:45
-
Maybe you are bitten by this bug: https://connect.microsoft.com/VisualStudio/feedback/details/521147/large-object-heap-fragmentation-causes-outofmemoryexception
In this case, adding
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
GC.WaitForPendingFinalizers();
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
in the loop might help.
Or use sos.dll http://www.codeproject.com/KB/dotnet/Memory_Leak_Detection.aspx to see, where you leak memory.

- 23,186
- 6
- 42
- 92
You have a lot of calls to various classes, ImageBody,Rgb2Hsi,BlackPatchDetection etc
I assume these are you own code. Any of these could be holding on the resources.
I would suggest you grab a profiler and run some tests.
Most of them have trial versions giving you a couple of days with it.
Try to take the Bitmap originalBMP = new Bitmap(filePath);
in a using()
using (Bitmap originalBMP = new Bitmap(filePath)) {
// your code....
sw.Flush();
}
All within the using() clause is definitly disposed after leaving the clause. You could also set you variables to null, after they are disposed.

- 1,311
- 3
- 13
- 26
-
I've got another question to this subject: When (any why) should I set variables null? Aren't they collected anyway when I leave their scope (talking about locals)? – Matthias Meid Apr 01 '10 at 11:24
-
You should use the using statement instead of Dispose() whereever possible. This way, you see in the declaration immediately that this instance you just create is freed.
Which is better?
Bitmap bmp = new Bitmap(filePath);
// .. pages of code goes here ..
bmp.Dispose(); // hopefully not forgotten
or
using (Bitmap bmp = new Bitmap(filePath))
{
// .. pages of code goes here ..
}
The using statement also ensures that all instances are freed even if you leave the current block/method prematurely with return,break or even an exception.
Note that you can put multiple assignments into the head of the using statement!

- 28,510
- 21
- 92
- 151
-
you have still lots of images in your code which are not disposed. Additionally, did you have a look at ImageBody? Does this class derive from IDisposable? If so you should also dispose it. – codymanix Apr 01 '10 at 15:22
-
You should also use .net memoryprofiler to see which objects consume so much memory – codymanix Apr 01 '10 at 15:23
As with any Garbage collection issue, my approach would be to start commenting things out and seeing if I can still reproduce memory leaks. Things to try out:
- Instantiate only one instance of
Bitmap
in the loop to see if the memory usage changes. - Dispose/not Dispose that one instance of Bitmap to see if disposing makes any difference.
From what I can see in the latest version of the code, whiteCoatBitmap
, yellowCoatBitmap
and blackPatchBitmap
are not being disposed. Surround those with a using block as well.

- 74,528
- 26
- 112
- 128