When is SystemTimers.Timer considered garbageif no reference is saved? - c#

I am very curious to know when a System.Timers.Timer is considered garbage and therefor collected by the Garbage Collector if I do not store a reference to it, but it is Enabled.
But at what point is my Timer considered garbage?
Consider the following code:
public void TriggerUpdateStatus() {
toolStripStatusLabel1.Text = "*";
new Timer() {
Interval = 1000,
Enabled = true
}.Elapsed += new ElapsedEventHandler(
(object sender, ElapsedEventArgs args) => {
toolStripStatusLabel1.Text = "";
Timer t = ((System.Timers.Timer) sender);
t.Stop();
t.Dispose();//Is this needed?
});
}
This block of code will run once every two seconds when my code triggers an update, it then adds a star character in the bottom corner of my form, indicating that the connection is alive and well. I create a Timer with no reference that will simply remove the star again after a second, stop it self and dispose of itself.

No, t.Dispose(), isn't necessary, it will be collected regardless.
The question itself seems to convey a deep misunderstanding about how the GC and Dispose work (I stress the word seems). The GC has absolutely no idea what Dispose does and couldn`t care less. That an object is disposed or not doesn't come in to play as to wether that particular object is elegible for collection; these are two completely orthogonal concepts.
Dispose is there as a mechanism to release unmanaged resources, it has nothing to do with how the garbage collector works.
If that is clear, then Dispose, although polite, isn't even strictly necessary; Dispose (or the needed part of it) will run anyway when the timer is eventually collected (the object is unreachable and short lived so it shouldn't take too long), put in the finalizer queue and finalized in some undetermined future; it is polite and recommended to dispose in order to deterministically release all unmanaged resources associated with the object instead of relying on whenever the finalizer queue decides to run, which brings up the next point:
Why are you newing up a Timer every two seconds and then disposing it immediately? Wouldn't it be much easier to have one single timer and reset it every time?

Related

c# my destructor isn't being called?

I have this simple code and trying to call the destructor but I can't call it :(
I know that GarbageCollector runs when it's necessary, so I used GC.WaitForPendingFinalizers(); but it didn't work either.
Here is my code:
class Program
{
static void Main(string[] args)
{
Calculator calculator = new Calculator();
Console.WriteLine("{0} / {1} = {2}", 120, 15, calculator.Divide(120, 15)
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine("Program finishing");
}
}
class Calculator
{
// Constructor
public Calculator()
{
Console.WriteLine("Calculator being created");
}
// Public Divide method
public int Divide(int first, int second)
{
return first / second;
}
// Destructor
~Calculator()
{
Console.WriteLine("Destructor is called");
}
}
And here is my output:
Calculator being created
120 / 15 = 8
Program finishing
What am I doing wrong? Why can't I see "Destructor is called" ?
The lifetime of a local variable is the lifetime of the activation of control within the local variable scope that declares it. So your local is alive until the end of main. That alone is sufficient to explain why it is not collected, but there are subtleties here that we should explore in more depth.
The lifetime may be extended by a variety of mechanisms, including capturing outer variables by a lambda, iterator blocks, asynchronous methods, and so on.
The lifetime is permitted to be shortened in cases where the jitter can prove that doing so has no effect on the single-threaded flow of control. (You can use KeepAlive to ensure this shortening does not happen in cases where you must avoid it.)
In your case, the runtime is permitted to notice that the local is never read from again, mark it as dead early, and thereby orphaning the reference to the object, which would then be collected and finalized. It is not required to do so, and apparently, in your case, does not.
As another answer correctly notes: the GC will deliberately suppress this optimization if it detects that a debugger is running, because it is a bad user experience for an object to be collected while you are examining a variable containing a reference to it in the debugger!
Let's consider the implications of my statements about shortened lifetimes, because I think you may not have fully grasped those implications.
The runtime is permitted to notice that the ctor never accesses this.
The runtime is permitted to notice that divide never accesses this.
The runtime is permitted to notice that therefore the local is never actually read from and used
Therefore the object is permitted to be never rooted in the GC at any point in its lifetime.
Which means that the garbage collector is permitted to run the finalizer before the constructor.
The GC and finalizer runs on their own threads, remember; the operating system could suspend the main thread and switch to the gc and finalizer threads at any point, including after the allocator runs but before control passes to the constructor.
Absolutely crazy things are permitted to happen in scenarios like the one you wrote; the finalizer not running is the least of your problems! It is when it could run that is scary.
If that fact was not immediately clear to you, then you have no business writing a finalizer. Writing a correct finalizer is one of the hardest things to do in C#. If you are not an expert on all the fine details of the CLR garbage collector semantics, you should not be writing a finalizer.
For more thoughts on how writing a finalizer is difficult, see my series of articles on the subject, which begins here:
https://ericlippert.com/2015/05/18/when-everything-you-know-is-wrong-part-one/
If you run a program with the debugger attached it changes the behavior of the lifetime of objects.
Without the debugger a object becomes ellagable for collection as soon as the last use of the object has been passed in the code. With the debugger attached the lifetime of all objects get extended to the entire time the object is in scope, this is done so you can view the object in the Watch window of the debugger and not have the object collected out from under you.
You must either run your program in release mode without the debugger attached or set calculator to null before you call GC.Collect() to be able to have the object be eligible for garbage collection and have it's finalizer run.
I would not recommend to really on destructors .net
anyway in your case GC don't think your object is garbage at the moment you calling GS because you have alive link in your stack calculator which is point to object in heap
so you can try to modify this code
main(){
DoCalculations();
//at this point object calculator is garbage (because it was allocated in stack)
GC.Collect();
}
DoCalculations(){
Calculator calculator = new Calculator(); // object allocated
calcualtor.doSomething(); //link alive
}

Is memory released on Form.close()?

I am working on feedback application which have lots of form open and close operation. I noticed few changes in memory changes in my application when i start my application it takes 25 MB. With each feedback user give it increases 3 MB in memory usage. On every form i had used this.close() when it jumps from one to other or there is any close operation. What can be the possible reason of memory increases.
Do i need to call garbage collector manually, as everyone says its not good practice.
In this i am using dual monitor scenario in which application take snapshot of secondary screen after each 500 ms and shows it on primary screen. For this I am using the code shown below:
public EntryForm()
{
sc = Screen.AllScreens;
dbDms = new HondaDb(UtilityFunctions.getServerConnection());
db = new HondaDb(UtilityFunctions.getClientConnection());
bmpScreenshot = new Bitmap(sc[1].Bounds.Width,
sc[1].Bounds.Height,
PixelFormat.Format32bppArgb);
Create a graphics object from the bitmap.
gfxScreenshot = Graphics.FromImage(bmpScreenshot);
Timer timerClientScreen = new Timer();
timerClientScreen.Interval = 500;
timerClientScreen.Enabled = false;
timerClientScreen.Start();
timerClientScreen.Tick += new EventHandler(timer_TickClient);
}
void timer_TickClient(object sender, EventArgs e)
{
// Take the screenshot from the upper left corner to the right bottom corner.
gfxScreenshot.CopyFromScreen(sc[1].Bounds.X, sc[1].Bounds.Y,
0, 0, sc[1].Bounds.Size, CopyPixelOperation.SourceCopy);
// Save the screenshot to the specified path that the user has chosen.
pictureBoxClient.Image = bmpScreenshot;
}
For closing of form on open of other I am using the code below
formOpen.show();
formClose.Close();
Suggest me how can I save memory usage.
It does, but just your UI objects. It isn't automatic for the variables you use. In an app like this, using big objects that take very little GC heap space but lots of unmanaged resources, the garbage collector doesn't typically run often enough to keep you out of trouble. You have to help and explicitly dispose the objects so you don't leave it up to the GC to take care of the job.
It may take too long for it to start running, you can build up a lot of unmanaged memory usage before it gets to run the finalizers. Potentially crashing your program with OOM, although you are still very far removed from that problem. Right now you are just running "heavy".
Add an event handler for the FormClosed event. You need to call the Dispose() method on the gfxScreenshot and bmpScreenshot objects. And surely those HondaDb objects need some kind of cleanup as well.
Do not assume that will instantly solve memory usage increments, the GC is not eager to release address space back to the operating system. Keeping it around instead with the assumption that you are likely going to have a need for it soon. The proper usage pattern is it stabilizing after a while at a reasonable number, then suddenly dropping and building back up. A saw-tooth pattern. Write a little unit test that calls creates and destroys your form object repeatedly, ensuring that it does the non-trivial jobs of taking the screenshot and accessing the dbase. Now you know with confidence that you don't have a run-away leak problem.
No, when you call Form.Close() you are just telling to close the form. the object is still there in memory and if you have a reference to it, it will be there until you have held that reference.
.NET has automatic garbage collection mechanism which collect objects that are garbage (you have no reference to them and they can not be accessed). So objects are removed from memory when they become garbage and .NET garbage collector starts it works. You can force executing garbage collector by calling GC.Collect().
More about GC
Have a look at this MSDN Thread. It's about dispoable Windows, this should release all ressource held by a an instance of a class. Then the garbage collector should do it's work.

Does GC.KeepAlive clean OnTimeEvent Variables and classes types?

I have a Timer function that I'm calling it from the Application_Start in the global.asax
this is the class:
public class AlertTimer
{
public AlertTimer()
{
//
// TODO: Add constructor logic here
//
}
static System.Timers.Timer aTimer = new System.Timers.Timer();
public static void Start()
{
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
aTimer.Interval = 30000;
aTimer.Enabled = true;
GC.KeepAlive(aTimer);
}
public static void OnTimedEvent(object source, ElapsedEventArgs e)
{
PresenceService ps = new PresenceService();
ps.GetAbsenceContacts(); //takes 10 seconds
}
}
Now , My question is if this class type PresenceService ps = new PresenceService(); is getting clean after the timer done with the run, or the GC is keeping it in the memory and start a new one every time that the OnTimedEvent run.
thanks!
conclusion: To remove GC from the code. Tnx!
Now , My question is if this class type PresenceService ps = new
PresenceService(); is getting clean after the timer done with the run,
or the GC is keeping it in the memory and start a new one every time
that the OnTimedEvent run.
Yes.
The instance of PresenceService will leave scope, and therefore be subject to garbage collection. However, since GC is mostly indeterministic, it is still in memory until such time as it's reclaimed. Therefore, on object's that do things and have life cycles (like timers for example) it's good to call some type of "shutdown" method.
However, the larger question I have is why you're running a timer in a web app and why you feel the need to call any methods directly on the Garbage collector. This is generally a sign that something is off about your application.
The ps instance will be eligible for garbage collection when OnTimedEvent ends.1 Well, that is assuming, of course, that PresenceService does not somehow root its own reference (via a static variable, etc.).
Also, GC.KeepAlive is not needed in this case. The reason is that aTimer is static so its lifetime is already tied to the application domain. In other words, aTimer is not eligible for collection at any point in the Start method because it is semi-permanently rooted by the static variable.
GC.KeepAlive is used in scenarios where the GC gets overly aggressive. When you compile the application with the release configuration and run it outside of the debugger the GC will mark object instances eligible for collection even before they go out of scope. For example, ps could be collected even before GetAbsenceContracts completes! GC.KeepAlive basically turns that optimization off. You typically see it used in unmanaged interop scenarios where you pass an object reference to an unmanaged API. Because the GC does not know anything about what is going on in the unmanaged realm it may mistakenly think the reference is no longer used and collect it prematurely.
1Technically, this is not exactly correct. The instance is eligible for collection when the GC thinks it is no longer used. It really has little to do with whether or not it is still in scope.

Unnamed timer thread doesn't execute

Wondering if someone can answer something that has stumped me.
I have a Timer that sets a variable to let some other threads know when to stop execution (the length is hard coded for this example)
Timer endProcessingThread = new Timer(x => _endOfProcessingTimeHasElapsed = true, null, 10000, 0);
I don't ever join on the thread or use the timers variable name for anything so I 'cleaned' it up to say:
new Timer(x => _endOfProcessingTimeHasElapsed = true, null, 10000, 0);
This compiles fine but the thread never executes.
Anyone know why?
My guess is that the Timer is going out of scope and being GCed before the 10 seconds are up. From MSDN:
As long as you are using a Timer, you must keep a reference to it. As with any managed object, a Timer is subject to garbage collection when there are no references to it. The fact that a Timer is still active does not prevent it from being collected.
The solution is to keep that reference at whatever code level will still be around in 10 seconds (or whenever) by assigning it to some class or form property/field.
First of all: Timer is IDisposable, so that you should use the timer’s variable name, at least to dispose it properly.
And: Since you do not keep any reference to the created instance, it is eligible for garbage collection. And since the internals of the Timer use a finalizer, the finalizer gets called and the timer gets deleted before it had a chance to fire. (Note that just keeping a reference in a named local variable as in your first case is not enough, the compiler might notice the variable is not used at all and garbage collect the instance anyway.)
Solution: Keep the reference and call Dispose() as soon as you finished using it.
This compiles fine but the thread never executes.
The anonymous Timer is possibly cleaned up by the Garbage collector before it triggers.
See this SO question.
It could be that since you never hold a reference to the object you create, it either gets optimized away immediately (no lvalue) or it simply get GC'd and never executes.
FWIW doesn't that class implement IDisposable? If so, you should be using a using statement or calling dispose.

Memory leak happens when using thread inside another thread

Below sample code has memory leak. If I comment out the two lines inside RefreshTimer_Elapsed, then the memory leak is gone. Does anybody know what's wrong? Thanks for help.
static void RefreshTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
Thread innerThread = new Thread(delegate() { });
innerThread.Start();
}
static void Main(string[] args)
{
System.Timers.Timer RefreshTimer = new System.Timers.Timer();
RefreshTimer.Interval = 5000;
RefreshTimer.Elapsed += new System.Timers.ElapsedEventHandler(RefreshTimer_Elapsed);
RefreshTimer.Start();
for (; ; )
{ }
}
Are you sure theres a memory leak? Or do you notice that your memory just grows?
Until the garbage collector cleans up all the threads you create, memory will grow, but its not leaking, the garbage collector knows that this is dead memory.
The only way memory "leaks" in a managed enviroment like .NET or java is when you have objects being referenced that are never used or needed. Thats not the case here. You're just creating a bunch of threads and forget about them immediately. As soon as they're no longer referenced by RefreshTimer_Elapsed and the thread stops running then there are no more references and they are free to be cleaned.
You won't see the memory drop until the garbage collector is ready to do a cleanup. You can try and force this but its not generally recommended for performance reasons.
What you see might be just resources not yet reclaimed by the Garbage collector because there is no memory pressure.
Also you have a busy for loop in your Main routine, you probably want a Thread.Sleep statement there for testing, unless this is somehow part of this test...
To force a garbage collection just for your testing only you could replace your for loop with:
while(true)
{
Thread.Sleep(5000);
GC.Collect();
GC.WaitForPendingFinalizers();
}
In general when examining 'memory leaks' or resource problems in managed code I would recommend using a profiler (i.e. Redgate ANTS) and take a closer look at the allocations over time.
I think it's because you keep creating new threads.
The Timer object needs to be disposed!
It appears you are creating new items as there is a recursive call of the code and there may be some kind of loop developing at runtime causing untidy filling of memory with multiple copies of objects as every called item does not fully complete.
RefreshTimer_Elapsed makes a new thread every interval. What kind of work is the anonymous method doing? Is it completing? Every thread you make will get 1MB of virtual memory allocated via Windows.
If you threads never finish, then every interval, you will consume another 1MB of memory.

Categories

Resources