473,395 Members | 1,977 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

"Simple" animation in C# --> memory leaks???

Hello all,

I am trying to write a "simple" animation using C#, and I've tried many
things but nothing seems to work for me without leaking memory. Here's
a very simple piece of code that uses a timer to set the image of a
label from an ImageList every 100ms or so. This is what was being used
when I inherited this piece of code, and I thought it was OK, until I
changed the size of the label to do animation on a larger piece of
screen real-estate.

-----------------------------------------
public void Timer_Tick(object sender, EventArgs e)
{
if (isAnimating)
{
pic_index = ++pic_index % 18;
this.label1.ImageIndex = pic_index;
}
else
{
this.timer1.Enabled = false;
}
}

-----------------------------------------

The form has a start and stop button, and the label. The imagelist has
18 images in it. I start it and it runs and leaks memory like a sieve!
The "in memory" footprint will shrink if I minimize the app, but we're
running on an embedded PC and there is NO virtual memory available, so
we are running full screen all the time.

I've tried other approaches such as double buffering, and that leaks
about 4k bytes / second at 10 refreshes per second. Here's the "tick"
method from that attempt:

-----------------------------------------
public void Timer_Tick(object sender, EventArgs e)
{
if (isAnimating)
{
pic_index = ++pic_index % 18;
Graphics AnimG = screen.getGraphics(); // gets an offscreen "copy"
screen.erase();
spriteArray[pic_index].draw(AnimG); // draw to the copy
screen.flip(); // blt
AnimG = null;
}
else
{
this.timer1.Enabled = false;
}
}
-----------------------------------------

The imagelist example acts like it's "copying" the image out of the
image list and storing it into some permanent (semi-permanent) data
structure someplace and keeping a strong reference to it. I don't even
have a theory as to what the double-buffering sample is doing, how it
could be leaking 4k bytes per second, any new objects created in the
tick method are destroyed at the end of it! In that method, I have 18
"sprites" where one gets painted to the buffer each tick and the buffer
is blt-d to the screen on a panel. That's about as simple as you can
make it.

The only thing I can figure is I'm using the timer wrong - somehow.
I've copied samples off the 'net, I don't "start" the timer anymore,
just enable or disable it.

Anybody have any clues as to what I've done wrong? I've done
animations for years in Java, and NEVER seen anything like this. I
"stumbled" on the memory leak issue because we ran our embedded PC out
of memory so fast it (the app not the PC) crashed in about 30s.

I'm frustrated and developing a VERY bad taste for C#.

Thanks in advance.

Nov 17 '05 #1
8 3670
I haven't done enough coding with the compact framework to be sure what
is in it, but I feel that some calls to the garbage collector could
help. I say this because you say the memory issue is solved with
minimizing. In regular C# coding you can invoke the garbage collector
with the code GC.Collect(). So try and see if that is in the CF or not
and if so see what happens when you call it after every redraw.

Also, as for the timer, I prefer to use Thread.Sleep() for timed
events. It just seems to be more solid. Hope this helps ~ Justin

Nov 17 '05 #2
Thanks Justin,

That does seem to work. But why on earth does it require an _explicit_
call to GC in order to recover memory, and why does the app happily
crash before at least trying to run GC?

Microsoft - are you listening? Is this half-baked or what?

-Scotty

Nov 17 '05 #3


"Beam_Us_Up_Scotty" wrote:
Thanks Justin,

That does seem to work. But why on earth does it require an _explicit_
call to GC in order to recover memory, and why does the app happily
crash before at least trying to run GC?

Microsoft - are you listening? Is this half-baked or what?


MS product feedback and bug reporting site.

http://lab.msdn.microsoft.com/produc...k/default.aspx

Not keeping enough memory free to allow the GC to collect without requesting
more from the system does appear to be a bug, probably from a missed test
case.
Nov 17 '05 #4
Justin wrote:
Also, as for the timer, I prefer to use Thread.Sleep() for timed
events. It just seems to be more solid. Hope this helps ~ Justin


Note that Thread.Sleep() will 'sleep' the current thread, but it also
allows other threads to work. I guess this is why you find it more
'solid' because calling it will not impact other work being done on
other threads in the process. Indeed, if you want to 'switch' to another
thread in your process on a single processor machine you can call
Thread.Sleep(0).

Richard
--
http://www.grimes.demon.co.uk/workshops/fusionWS.htm
http://www.grimes.demon.co.uk/workshops/securityWS.htm
Nov 17 '05 #5
Beam_Us_Up_Scotty wrote:
-----------------------------------------
public void Timer_Tick(object sender, EventArgs e)
{
if (isAnimating)
{
pic_index = ++pic_index % 18;
Graphics AnimG = screen.getGraphics(); // gets an offscreen "copy"
screen.erase();
What is this screen object? How is getGraphics implemented?

I suspect you are doing something like a call to Graphics.FromHWND() or
FromImage(). If you implement it using one of these methods (or similar)
then you must release the graphics object after you have finished using
it, see below...
spriteArray[pic_index].draw(AnimG); // draw to the copy
screen.flip(); // blt
Anim.Dispose();
AnimG = null;
Doing this will just mark the object as being available for garbage
collection sometime in the future, but you have no idea when that will
be. The graphics object's finaliser effectively calls Dispose(). Calling
Dispose explicitly will clean up the resources immediately.

Better still, the device context will not change during the animation,
so you do not need to create a new Graphics object for each tick.
Instead, create it once and then cache it. Therefore you
screen.getGraphics will return the cached Graphics object. In this case
DO NOT Dispose the Graphics object in the tick method.
I'm frustrated and developing a VERY bad taste for C#.


To be honest, this has nothing to do with C#, it is an issue with
non-deterministic finalization, which is a .NET issue, and anyway, Java
has just the same problems.

Richard
--
http://www.grimes.demon.co.uk/workshops/fusionWS.htm
http://www.grimes.demon.co.uk/workshops/securityWS.htm
Nov 17 '05 #6

"Justin" <ju***********@gmail.com> wrote in message
news:11*********************@g49g2000cwa.googlegro ups.com...
I haven't done enough coding with the compact framework to be sure what
is in it, but I feel that some calls to the garbage collector could
help. I say this because you say the memory issue is solved with
minimizing. In regular C# coding you can invoke the garbage collector
with the code GC.Collect(). So try and see if that is in the CF or not
and if so see what happens when you call it after every redraw.

Also, as for the timer, I prefer to use Thread.Sleep() for timed
events. It just seems to be more solid. Hope this helps ~ Justin

You should never call GC.Collect on disposable objects, Dispose them of when
done with them.

Willy.
Nov 17 '05 #7

"Beam_Us_Up_Scotty" <sc**************@swisslog.com> wrote in message
news:11**********************@z14g2000cwz.googlegr oups.com...
Thanks Justin,

That does seem to work. But why on earth does it require an _explicit_
call to GC in order to recover memory, and why does the app happily
crash before at least trying to run GC?

Microsoft - are you listening? Is this half-baked or what?

-Scotty


Images are unmanaged resources (they are loaded in the process heap not in
the GC heap), so you need to call Dispose to release them, the GC has
nothing to do with unmanaged memory. When calling GC.Collect() you force the
finalizer to run, and the finalizer will call Finally" on the Graphics
object and this one will release the unmanaged memory, but you shouldn't do
that, call Dispose or use a using statement block like this:.

pic_index = ++pic_index % 18;
using(Graphics AnimG = screen.getGraphics())
{
screen.erase();
spriteArray[pic_index].draw(AnimG); // draw to the copy
screen.flip(); // blt
// no need to set AnimG to nul here, this is taken care of by the Finaly
method.
}
Willy.
Nov 17 '05 #8

"Dan Neely" <Da******@discussions.microsoft.com> wrote in message
news:5E**********************************@microsof t.com...


"Beam_Us_Up_Scotty" wrote:
Thanks Justin,

That does seem to work. But why on earth does it require an _explicit_
call to GC in order to recover memory, and why does the app happily
crash before at least trying to run GC?

Microsoft - are you listening? Is this half-baked or what?


MS product feedback and bug reporting site.

http://lab.msdn.microsoft.com/produc...k/default.aspx

Not keeping enough memory free to allow the GC to collect without
requesting
more from the system does appear to be a bug, probably from a missed test
case.


Not sure where you get this from, Graphic objects do wrap unmanaged
resources (memory and GDI handles) and therefore implements the Dispose
pattern, failing to call Dispose in a timely fashion (say when done with it)
will result in a program failure as you will exhaust the GDI objects handles
(these are limited unmanaged resources) available to the process, the GC
will never kick in here because it has no knowledge of such resources.
Willy.
Nov 17 '05 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Maurice | last post by:
Hi there, I'm experiencing big memory problems on my webserver. First on an old RedHat 7.2 system, now on an other fresh installed Suse 8.2 system: Linux version 2.4.20-4GB...
2
by: Generic Usenet Account | last post by:
I have been using STL for a long time now, without any problems. Recently we generated a purification report on our software using Rational Purify, and we found some memory leaks. My colleague...
3
by: laniik | last post by:
Hi. I was wondering if there were any known leaks using STL vectors. Also, I was wondering if I have to do any sort of deleting or memory clearing when im done with the vector, or will they be...
0
by: Frank Lopez | last post by:
Does anyone know if Microsoft generated a whitepaper on this topic? Does anyone know what the solution is? (meaning, eliminate the leak problem -- I am seeing three memory leaks from...
10
by: darkStar_e2 | last post by:
Hi guys. I have an applications which unfortunately eating up all the computer resources. the this is that it is not releasing the resources (memory) that it has eaten after it was closed... how...
4
by: ali.jan | last post by:
Hi, It is trivial to load an assembly in a new Application Domain. Is there any way of loading an assembly in a new process? I tried using the Process class like this: Process p = new...
3
by: Jim Land | last post by:
Jack Slocum claims here http://www.jackslocum.com/yui/2006/10/02/3-easy-steps-to-avoid-javascript- memory-leaks/ that "almost every site you visit that uses JavaScript is leaking memory". ...
6
by: nmehring | last post by:
I have an MFC app with 2000 users. I have one user that experiences a crash in our software anywhere from 1 to 5 times a week when opening a particular module. No other users have reported this...
11
by: dhtml | last post by:
(originally mis-posted on m.p.s.jscript...) I've just closed all windows in Firefox and its using 244MB of memory. I have no idea why. I had GMail open, a page from unicode, the CLJ FAQ. ...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.