title: VB.NET - Memory leak using while true loop, threads and wmi
body: <p>this code starts using 40 MB RAM and after 2 hours goes to 120 MB RAM. I tried to change some lines, but the used memory still goes up and up. What am I doing wrong? Is the while loop? Is the theads? Is the ContextDB.SaveChanges()?</p>
  
  <p><strong>UPDATE 1</strong>: Apparently the problem was resolved using "IsBackground = True" on the threads and disposing each "m" object. The used RAM is stable in 48 MB. Thanks guys.</p>
  
  <pre><code>Dim Work As New Thread(AddressOf MonitorServer)
  Work.IsBackground = True 'Added this line
  Work.Start(Server.ServerID)
  
  Using searcher As New ManagementObjectSearcher(Scope, New ObjectQuery("SELECT * FROM Win32_OperatingSystem"))
      Using queryCollection = searcher.Get()
          For Each m In queryCollection
              Server.Host = m("csname")
              Server.OS = m("Caption")
              m.Dispose() 'Added this line
              m = Nothing 'Added this line
          Next
      End Using
  End Using
  </code></pre>
  
  <p>.</p>
  
  <p><strong>UPDATE 2</strong>: The problem continues, after 24h, the code was using <strong>350 MB</strong> !!!!</p>
  
  <p>.</p>
  
  <p><strong>ORIGINAL CODE:</strong></p>
  
  <pre><code>Full code: http://200.98.144.175/monitor.txt
  
  Private Shared ServerList As New List(Of Server)
  
  Private Shared Sub StartMonitor()
  
  Using ContextDB As New EnvironmentMonitorEntities
  
      While True
  
          Dim Servers = (From A In ContextDB.Server).ToList
  
          For Each Server In Servers
  
              If Not ServerList.ToList.Contains(Server) Then
  
                  ServerList.Add(Server)
  
                  Dim Work As New Thread(AddressOf MonitorServer)
                  Work.Start(Server) 'Start a thread for each server
  
              End If
  
          Next
  
          GC.Collect() 'Force CG
          Thread.Sleep(CInt(TimeSpan.FromSeconds(10).TotalMilliseconds)) 'Check new servers each 10 seconds
  
      End While
  
  End Using
  
  End Sub
  
  Private Shared Sub MonitorServer(p As Object)
  
  Dim Server = CType(p, Server)
  
  Using ContextDB As New EnvironmentMonitorEntities
  
      While True
  
          Dim ServerID = Server.ServerID
          Dim ServerStatus = (From A In ContextDB.ServerStatus Where A.ServerID = ServerID).First
          Dim Scope As New ManagementScope("\\" + Server.IP + "\root\CIMV2")
  
          ServerStatus.LastUpdate = Now
          ContextDB.SaveChanges()
  
          Scope.Connect() 'Connect on server
  
          Alerts.SetServerStatus(ServerStatus, AlertType.Online)
          ContextDB.SaveChanges()
  
          Using searcher As New ManagementObjectSearcher(Scope, New ObjectQuery("SELECT * FROM Win32_OperatingSystem"))
              Using queryCollection = searcher.Get()
                  For Each m In queryCollection
                      Server.Host = m("csname")
                      Server.OS = m("Caption")
                  Next
              End Using
          End Using
  
          ContextDB.SaveChanges()
  
          Using searcher As New ManagementObjectSearcher(Scope, New ObjectQuery("SELECT * FROM Win32_Processor"))
              Using queryCollection = searcher.Get()
                  For Each m In queryCollection
                      Server.Processor = m("Name")
                      Server.Architecture = m("Architecture")
                  Next
              End Using
          End Using
  
          ContextDB.SaveChanges()
  
          Using searcher As New ManagementObjectSearcher(Scope, New ObjectQuery("SELECT * FROM Win32_OperatingSystem"))
              Using queryCollection = searcher.Get()
                  For Each m In queryCollection
                      ServerStatus.RAMUsage = m("FreePhysicalMemory")
                      ContextDB.SaveChanges()
                  Next
              End Using
          End Using
  
          GC.Collect()
          Thread.Sleep(CInt(TimeSpan.FromSeconds(3).TotalMilliseconds)) 'Monitor server each 3 seconds
  
      End While
  
  End Using 'ContextDB
  
  End Sub
  </code></pre>