Solved

Memory Leak when throwing exception in VB .NET

Posted on 2007-04-04
8
667 Views
Last Modified: 2013-12-05
Hello All,

I have an VB .NET application for CF that throws an exception in a Threading.Timer. This seems to be leaking memory. A Forms.Timer works ok)

Stripped down the problemsource looks like this. The GC.Collect is just there for the remote performance monitor. I monitor the Managed Bytes In Use After GC ANd this keeps running up. I I compare GC Heaps I guess it is a ErrObject that is not released. I do not understand however how to do that.

Thanks in advance for any help.

Module Module1

  Public timMain As clsTimer = Nothing

  Sub Main()
    timMain = New clsTimer
    While True
    End While
  End Sub
  Public Class Test
    Sub ThrowEx()
      Try
        'This leaks
        Throw New Exception
      Catch ex As Exception
        ex = Nothing
        ' for NETCFRPM
        GC.Collect()
      End Try
    End Sub
  End Class

  Public Class clsTimer
    Delegate Sub DoSomething()
    Dim timTimer As System.Threading.Timer

    Public Sub New()
      timTimer = New System.Threading.Timer(AddressOf mHandleTimer, Nothing, 0, System.Threading.Timeout.Infinite)
    End Sub

    Private Sub mHandleTimer(ByVal source As Object)
      Dim clsTest As New Test
      Dim myThrowEx As DoSomething = AddressOf clsTest.ThrowEx
      myThrowEx.Invoke()
      timTimer.Change(1000, System.Threading.Timeout.Infinite)
      clsTest = Nothing
      myThrowEx = Nothing
    End Sub
  End Class


End Module


 
0
Comment
Question by:IrDuck
  • 3
  • 2
  • 2
8 Comments
 
LVL 7

Expert Comment

by:dctuck
Comment Utility
Try disposing of your timer once you are finished with it:

timTimer.Dispose()
0
 
LVL 7

Expert Comment

by:dctuck
Comment Utility
0
 

Author Comment

by:IrDuck
Comment Utility
Thanks, but actually the timer is not supposed to stop in the program. It is used to check if any file handling needs to be done, and runs as long as the program runs. I have however tested disposing the timer at a certain point but that does not return the memory leaked by the Exception throwing. In the .NET CF Remote Performance Monitor it is just the err.object and relates stuff that grows in instances, not the timer.

 
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 7

Accepted Solution

by:
multithreading earned 500 total points
Comment Utility
You don't have an actual "leak", it just looks that way. Your code is allocating little chunks of memory at at time. If you watch the memory allocation, it will keep climbing, and climbing, and climbing -- but always by little amounts. That is because the garbage collector is lazy. It doesn't kick in just because you have objects out there. It kicks in when the time feels right. Eventually it will level off. The GC is like a thermostat in your house. It doesn't kick on and off constantly. Ironically, if you were allocating bigger chunks of memory, it would force the GC to kick in quicker, and you would see your memory utilization more constant than it is in your program.

"Oh, but wait" ... "I have a GC.Collect() in there". Yes, but that is buried inside of memory allocations. If you were to move the GC.Collect() from where it is to the bottom of the mHandleTimer method, you would see memory stay much more stable. (You don't need to force the Collect at all, of course, it will kick in by itself eventually. Moreover, it is usually best not to force it, but I know you are doing this just for testing purposes.)

I know it is just a stripped down test, but if you would like to stop pegging your CPU at 100% utilization, change your
   While True
    End While
to something like
           System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite)

Now, there is one more lingering question: "Why didn't it behave this way in my forms application?" Your forms application is allocating memory constantly. All of the little window events generate messages, which often result in managed allocations, which keeps the GC humming more frequently.
0
 

Author Comment

by:IrDuck
Comment Utility
Hi, Thanks for the clear explanation. Maybe I am looking at the wrong thing. (Sometimes you mess up more by monitoring than you solve). However, I ran a Device Application version of this program for a long time and it actually crashed on a memory error. I have tried to run this console application for a long time this morning on reduced memory, and actually after a few hours the device became much slower.  I move the GC.Collect as you suggested and ran the program through NETCFRPM but still noticed the value Managed Bytes After GC running up (as far as I know that is an indication for a memory leak). I run the program on CE 5.0 and CF 2.0. (In real life btw there is no GC.Collect in the program and the exception is only thrown in certain circumstances so the memory will last for about a weak before a reset is needed.) Hope you have some more suggestions, thanks in advance.  
0
 
LVL 7

Expert Comment

by:multithreading
Comment Utility
I don't have Console capability on my CE device. Someone else is going to have to jump in here. It looks like it is specific to console applications on CE as your code runs without leaking on XP.
0
 
LVL 7

Expert Comment

by:multithreading
Comment Utility
It was an aside earlier, but maybe the garbage collector thread is competing with your CPU-bound infinite loop in your Main. That thing really jumps off the page.

  While True
   End While

If you want to wait forever, use System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite)
0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
Windows 8 came with a dramatically different user interface known as Metro. Notably missing from that interface was a Start button and Start Menu. Microsoft responded to negative user feedback of the Metro interface, bringing back the Start button a…
With the advent of Windows 10, Microsoft is pushing a Get Windows 10 icon into the notification area (system tray) of qualifying computers. There are many reasons for wanting to remove this icon. This two-part Experts Exchange video Micro Tutorial s…

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now