memory leak

R

raju

Hai

In my device application (windows ce application using vb.net), i
am having nearly 25 forms. Moving from one form to another form, just i
am hide the first form and show the second form.

Each form I am having some picturebox, putting images for that
picturebox using imagelist.

My application works very well. But, if the application running
contineously for 1 or 2 hours, i am getting error such as "low memory".


when i checked the memory, it will automatically increasing when
the application is in running. First initial time, it occupies 22 mb
and it increasing upto 32 to 35 mb.

What is the reason for this? and how to correct this memory
problem.

Regards
Raju.
 
G

Guest

Are you properly disposing resources? Have you tried to profile it with
RPM? Have you tried to narrow down where the problem may be? With the info
you've given, it really could be anything.

-Chris
 
H

Hilton

I bet you're doing something like "xyz.Image = new Bitmap (...)" - right?
If so, there is a bug in the CF design/implementation (IMHO) that forces you
to do your own memory management; i.e. for every "new Bitmap ()" you do,
you'll need to do a "Dispose()" on that bitmap when you're done with it (aka
malloc and free).

Let us know if that helps,

Hilton
 
H

Hilton

Chris,

This has come up before, so no use beating a dead horse (I'm the guilty one
here since I first mentioned it), but here are some points which hopefully
helps to explain my comments:

1. If ALL objects were required to be disposed, would that be a design bug?
Of course it would, it is .NET with a garbage collector.
2. Then why do we have to dispose Bitmap? Because MS took a short-cut.
Note that MS have already said that they will *fix* this problem.
3. Another bad choice IMHO was to put Bitmap in System.Drawing - that is
the wrong place since you don't only draw with Bitmap and a Bitmap image
should not be directly associated with UI. It should be in System.Image or
something similar. Here is an example in pseudo-C#: Imagine you wanted to
convert all BMP files to PNG files using a command line EXE. It should
simply be "using System.Image; foreach BMPFile in directory { new Bitmap
(BMPFile).SaveAs (PNG); }" but instead we have to include System.Drawing
(UI stuff), plus we need to do our own memory management (the code above
would have a huge memory leak).
4. FWIW: I think Dispose should be an optional call, not a mandatory call
required to prevent a memory leak.
5. There are other things like why they called it SortedList instead of
SortedMap etc... (unrelated to Bitmap)

Bottom line, I love C#, work with it day in and day out, absolutely darn
amazing on Pocket PCs etc, so don't think for a second I'm bashing the C#
language, the .NET team, or Microsoft. Just sometimes, bad design decisions
get made (*IHMO*).

Hilton
 
G

Guest

I think there's still a misundestanding of the fundamentals.

Dispose is not a required call - it is optional. Your application knows
better than anything else when you are done with resources, and at that
point, you can call Dispose to let the GC know that you are done with those
resources. These classes are written so that during that call, managed
resources are released.

If you don't call Dispose, that's fine. When the GC goes to collect, it
will walk the roots. It will see that the Bitmap has no references, and it
will then run Dispose on it for you and move it to the Finalizer queue. On
the _next_ GC cycle, the actual Bitmap will be released. This all happens
automatically, without your intervention. It just happens late - when the
GC is collecting - likely because you're low on resources.

Calling Dispose is simply a good idea because it allows the release of
system resources when the app is done with them rather than waiting for the
system to GC.

For more info, take a look at my presentation from MEDC:
http://blog.opennetcf.org/ctacke/PermaLink,guid,e806d34b-a8d8-45e8-9de8-bec58818fafe.aspx
 
H

Hilton

Chris,

I agree there is a misunderstanding of the fundamentals. Run the short
program below and see for yourself. On the Pocket PC, the device runs out
of memory and throws an OutOfmemoryException; one the desktop, it used all
2GB that was free when it started and threw a "System.ArgumentException:
Invalid parameter used" on the "new Bitmap" line.

Now do you still agree that the GC will cleanup Bitmap objects? Sorry
Chirs, it doesn't happen as you say cause the "new Bitmap" code below that
*does not keep a reference to each bitmap* ran out of memory.

Hilton
----------------------------
Create a form, add a timer with the code:
this.timer = new Timer ();
this.timer.Interval = 250;
this.timer.Tick += new EventHandler(timer_Tick);
this.timer.Enabled = true;

then add this method:

private void timer_Tick(object sender, EventArgs ea)
{
bool error = false;

this.timer.Enabled = false;

try
{
this.bmp = new Bitmap (1024, 1024);

this.Text = DateTime.Now.ToLongTimeString();
}
catch (Exception e)
{
error = true;

using (System.IO.StreamWriter sw = new
System.IO.StreamWriter ("exp.txt"))
{
sw.WriteLine (e.ToString());
}

this.Text = "Exception";
}
this.timer.Enabled = !error;
}
---------------
 
G

Guest

I don't have Studio on this machine. What happens if you put a GC.Collect
in the exception handler, then allow it to continue?

-Chris
 
D

Doug Forster

Well I don't suppose its particularly relevant to the OP's problem, but I
just tried Hiltons little program on the desktop (VS2005) without the
explicit GC and it worked just as it should - memory climbed up to near 2GB
and then obviously GC'ed down to 70MB and then repeated the cycle, no
exceptions. If there was a problem its clearly been fixed on the desktop
anyway.

Cheers
Doug Forster
 
H

Hilton

Chris,

I did some more testing. Using CF 2.0 makes no difference - still throws
exception. Adding GC.Collect() causes the memory to drop, app keeps running
both on desktop and PPC. So, the OOM is not causing a GC.Collect() because
that would cause the OOM condition to go away, the "new" to then succeed
etc. Looks like they fixed this on the desktop in a later version of the
..NET Framework according to Doug's post. I'm still running 1.1.4322.2032.

Chris, do you agree? (given that my findings stated above are correct)

Hilton
 
V

vikash

Hi Raju

I am new to this group and dont have much experience.
As per my understanding and According to what u posted i have some
doubt.
Are u ensuring that only a single instance of any object u r using.
...like before creating any object with new() statement plz do check
if the instance already exists or not.

Plz ignore if it sounds kiddish.

// in global class / module declare this
public frm1 frm1()
{
if (m_frm1 != null)
{
return m_frm1;
}
else
{
m_frm1 = new frm1();
return m_frm1;
}
}

and call -

frm1().show();

this way u can check and use single instance.

Thanks & Regards
vikash
 
G

Guest

Sounds like an OOM on a bitmap allocation isn't triggering a GC like it
should. If that's the case, it's certainly a bug.

-Chris
 
G

Guest

Actually trying with CF 2.0 and using RPM would be interesting - you can
definitively see if GC is actually called when the OOM happens or not.

-Chris
 
H

Hilton

I find it interesting that the exceptions are different too (desktop versus
CF).

Ilya or anyone else from MSFT want to jump in here???

Hilton
 
G

Guest

Just FYI I'm running some tests on this and talking with the CF team about
what I'm seeing - the behavior is not as simple as either of us originally
thought. Once I have some definitive info I'll blog it.
 
H

Hilton

Chris,

Keep us posted, what is your blog address? I'm really interested in this
bug (as well as the stream.Close() bug in another thread).

Thanks,

Hilton
 
H

Hilton

That's not fair, you can't say "the behavior is not as simple as either of
us originally thought" and not tell me. :) Just kidding. Seriously
though, I'd love to find out more about this issue because everything we've
seen, it seems like the VM doesn't garbage collect before throwing an OOM on
..NET 1.1 and CF. On a scale of 1 to 10, that's pretty serious. Again, I'm
hoping I'm wrong and it is something simple.

Anything to add here or blog?

Thanks,

Hilton
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top