<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=us-ascii">
<META NAME="Generator" CONTENT="MS Exchange Server version 5.5.2658.2">
<TITLE>RE: [Mono-devel-list] Leak in System.Timers.Timer?</TITLE>
</HEAD>
<BODY>

<P><FONT SIZE=2>The test code I posted creates way more timers than I would in my actual code - so that the symptoms can be seem more readily. Perhaps this is not a valid test if the code produces objects faster than the gc collects them. I did run the same code creating 10 new Object()'s and changed the sleep to Sleep(0) and didn't see the memory rise. I don't know a lot of the internal workings of mono, so perhaps this isn't a fair test to see if my issue is related to the gc or not.</FONT></P>

<P><FONT SIZE=2>Also, I see the same problem running my app with many fewer timers being created only it takes several days to see the memory usage rise. Since the memory usage gradually climbs its not the easiest test case to use to reproduce the issue (you have to wait a long time), this is why I posted the modified code. </FONT></P>

<P><FONT SIZE=2>I did work around my problem by only creating a single timer and reusing it for the lifetime of my app so its no longer an issue for me.</FONT></P>

<P><FONT SIZE=2>-----Original Message-----</FONT>
<BR><FONT SIZE=2>From: Rafael Teixeira [<A HREF="mailto:monoman@gmail.com">mailto:monoman@gmail.com</A>] </FONT>
<BR><FONT SIZE=2>Sent: Friday, March 11, 2005 11:10 AM</FONT>
<BR><FONT SIZE=2>To: Kroeker, Brian [WIC:9D10:EXCH]</FONT>
<BR><FONT SIZE=2>Cc: mono-devel-list@lists.ximian.com</FONT>
<BR><FONT SIZE=2>Subject: Re: [Mono-devel-list] Leak in System.Timers.Timer?</FONT>
</P>
<BR>

<P><FONT SIZE=2>Our current gc, is conservative and not very aggressive at freeing</FONT>
<BR><FONT SIZE=2>resources, you may be creating your objects way too fast...</FONT>
</P>

<P><FONT SIZE=2>Can't you reuse the timer? Seems to be a wiser solution reuing objects</FONT>
<BR><FONT SIZE=2>as even a good gc may spend precious processing time if it has to</FONT>
<BR><FONT SIZE=2>collect zillions of short-lived objects...</FONT>
</P>

<P><FONT SIZE=2>Just my 2 cents, :)</FONT>
</P>
<BR>

<P><FONT SIZE=2>On Thu, 10 Mar 2005 15:07:55 -0500, Brian Kroeker &lt;bkroeker@nortel.com&gt; wrote:</FONT>
<BR><FONT SIZE=2>&gt;&nbsp; </FONT>
<BR><FONT SIZE=2>&gt;&nbsp; </FONT>
<BR><FONT SIZE=2>&gt; I haven't installed mono on windows but using the MS Framework I don't see</FONT>
<BR><FONT SIZE=2>&gt; this behavior on windows. Also I don't believe this could be a</FONT>
<BR><FONT SIZE=2>&gt; lapsed-listener, since I'm subscribing to an event in the instance of timer</FONT>
<BR><FONT SIZE=2>&gt; - when all references to timer are gone shouldn't the garbage collector get</FONT>
<BR><FONT SIZE=2>&gt; rid of the object including its event and list of delegates? I didn't think</FONT>
<BR><FONT SIZE=2>&gt; the delegates stuck around after the event went away. </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp; </FONT>
<BR><FONT SIZE=2>&gt; Brian </FONT>
<BR><FONT SIZE=2>&gt;&nbsp; </FONT>
<BR><FONT SIZE=2>&gt;&nbsp; </FONT>
<BR><FONT SIZE=2>&gt; -----Original Message-----</FONT>
<BR><FONT SIZE=2>&gt; From: mono-devel-list-admin@lists.ximian.com</FONT>
<BR><FONT SIZE=2>&gt; [<A HREF="mailto:mono-devel-list-admin@lists.ximian.com">mailto:mono-devel-list-admin@lists.ximian.com</A>] </FONT>
<BR><FONT SIZE=2>&gt; Sent: Thursday, March 10, 2005 12:03 PM</FONT>
<BR><FONT SIZE=2>&gt; To: mono-devel-list@lists.ximian.com</FONT>
<BR><FONT SIZE=2>&gt; Subject: Re: [Mono-devel-list] Leak in System.Timers.Timer?</FONT>
<BR><FONT SIZE=2>&gt; </FONT>
<BR><FONT SIZE=2>&gt;&nbsp; </FONT>
<BR><FONT SIZE=2>&gt; Oh, wait I see you are passing the same one by ref and setting it to null.</FONT>
<BR><FONT SIZE=2>&gt; Do you get different behaviour under windows? </FONT>
<BR><FONT SIZE=2>&gt; </FONT>
<BR><FONT SIZE=2>&gt; Joe Audette &lt;joe_audette@yahoo.com&gt; wrote: </FONT>
<BR><FONT SIZE=2>&gt;&nbsp; </FONT>
<BR><FONT SIZE=2>&gt; Looks to me like your creating timers in an infinite loop wich would of</FONT>
<BR><FONT SIZE=2>&gt; course continue to consume resources </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp; </FONT>
<BR><FONT SIZE=2>&gt;&nbsp; while(true) </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp;&nbsp;&nbsp; { </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InitTimeout(ref timeout); </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Threading.Thread.Sleep(10); </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp;&nbsp;&nbsp; } </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp; </FONT>
<BR><FONT SIZE=2>&gt; true will always be true so you are spinning off a lot of timers right? Or</FONT>
<BR><FONT SIZE=2>&gt; am I missing something? </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp; </FONT>
<BR><FONT SIZE=2>&gt; Regards, </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp; </FONT>
<BR><FONT SIZE=2>&gt; Joe</FONT>
<BR><FONT SIZE=2>&gt; </FONT>
<BR><FONT SIZE=2>&gt; </FONT>
<BR><FONT SIZE=2>&gt; Brian Kroeker &lt;bkroeker@nortel.com&gt; wrote:</FONT>
<BR><FONT SIZE=2>&gt;&nbsp; </FONT>
<BR><FONT SIZE=2>&gt;&nbsp; </FONT>
<BR><FONT SIZE=2>&gt; </FONT>
<BR><FONT SIZE=2>&gt; I'm seeing what looks like a memory leak somewhere in System.Timers.Timer.</FONT>
<BR><FONT SIZE=2>&gt; I'm using mono 1.1.4 on a linux system. The code I used to reproduce the</FONT>
<BR><FONT SIZE=2>&gt; problem is: </FONT>
<BR><FONT SIZE=2>&gt; </FONT>
<BR><FONT SIZE=2>&gt; ---------------------- </FONT>
<BR><FONT SIZE=2>&gt; using System; </FONT>
<BR><FONT SIZE=2>&gt;&nbsp; </FONT>
<BR><FONT SIZE=2>&gt; </FONT>
<BR><FONT SIZE=2>&gt; namespace TimerTest </FONT>
<BR><FONT SIZE=2>&gt; { </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp;&nbsp;&nbsp; public class TimerTest </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp;&nbsp;&nbsp; { </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static void Main(string[] args) </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TimerTest test = new TimerTest(); </FONT>
<BR><FONT SIZE=2>&gt; </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; test.Run(); </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </FONT>
<BR><FONT SIZE=2>&gt; </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public TimerTest() </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </FONT>
<BR><FONT SIZE=2>&gt; </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void Run() </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Timers.Timer timeout = null; </FONT>
<BR><FONT SIZE=2>&gt; </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while(true) </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InitTimeout(ref timeout); </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Threading.Thread.Sleep(10); </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </FONT>
<BR><FONT SIZE=2>&gt; </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void InitTimeout(ref System.Timers.Timer timer) </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(timer != null) </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; timer.Stop(); </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; timer = null; </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </FONT>
<BR><FONT SIZE=2>&gt; </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; timer = new System.Timers.Timer(); </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; timer.AutoReset = false; </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; timer.Elapsed += new</FONT>
<BR><FONT SIZE=2>&gt; System.Timers.ElapsedEventHandler(OnTimeout); </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; timer.Interval = 30000; </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; timer.Start(); </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </FONT>
<BR><FONT SIZE=2>&gt; </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void OnTimeout(object source, System.Timers.ElapsedEventArgs</FONT>
<BR><FONT SIZE=2>&gt; e) </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </FONT>
<BR><FONT SIZE=2>&gt;&nbsp;&nbsp;&nbsp;&nbsp; } </FONT>
<BR><FONT SIZE=2>&gt; } </FONT>
<BR><FONT SIZE=2>&gt; -------------- </FONT>
<BR><FONT SIZE=2>&gt; </FONT>
<BR><FONT SIZE=2>&gt; Does anyone else see this problem? Am I missing something here? I see the</FONT>
<BR><FONT SIZE=2>&gt; memory usage on my system increase fairly quickly. </FONT>
<BR><FONT SIZE=2>&gt; </FONT>
<BR><FONT SIZE=2>&gt; Thanks, </FONT>
<BR><FONT SIZE=2>&gt; Brian </FONT>
<BR><FONT SIZE=2>&gt; </FONT>
<BR><FONT SIZE=2>&gt; joe_audette@yahoo.com</FONT>
<BR><FONT SIZE=2>&gt; <A HREF="http://www.joeaudette.com" TARGET="_blank">http://www.joeaudette.com</A></FONT>
<BR><FONT SIZE=2>&gt; <A HREF="http://www.mojoportal.com" TARGET="_blank">http://www.mojoportal.com</A></FONT>
<BR><FONT SIZE=2>&gt; </FONT>
<BR><FONT SIZE=2>&gt; </FONT>
<BR><FONT SIZE=2>&gt; joe_audette@yahoo.com</FONT>
<BR><FONT SIZE=2>&gt; <A HREF="http://www.joeaudette.com" TARGET="_blank">http://www.joeaudette.com</A></FONT>
<BR><FONT SIZE=2>&gt; <A HREF="http://www.mojoportal.com" TARGET="_blank">http://www.mojoportal.com</A> </FONT>
</P>
<BR>

<P><FONT SIZE=2>-- </FONT>
<BR><FONT SIZE=2>Rafael &quot;Monoman&quot; Teixeira</FONT>
<BR><FONT SIZE=2>---------------------------------------</FONT>
<BR><FONT SIZE=2>I'm trying to become a &quot;Rosh Gadol&quot; before my own eyes. </FONT>
<BR><FONT SIZE=2>See <A HREF="http://www.joelonsoftware.com/items/2004/12/06.html" TARGET="_blank">http://www.joelonsoftware.com/items/2004/12/06.html</A> for enlightment.</FONT>
</P>

</BODY>
</HTML>