Solved

I am having a memory leak with a VB.net system service.

Posted on 2004-09-09
9
728 Views
Last Modified: 2007-12-19
Below you will find the code for a windows service that I created.  Everything is working as it should, but my memory on this just keeps climbing.

What this serviced does is every time a new pdf document is added to a folder, a check is performed.

The check is to loop through each file in the folder, check the file to see if is more than 60 min old and if so delete it.

The more times we add files and files get removed, the higher the memory goes.

Here is the code, and thank you for your time.


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


Imports System.ServiceProcess
Imports System
Imports System.IO

Public Class Service1
    Inherits System.ServiceProcess.ServiceBase

#Region " Component Designer generated code "

    Public Sub New()
        MyBase.New()

        ' This call is required by the Component Designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call

    End Sub

    'UserService overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    ' The main entry point for the process
    <MTAThread()> _
    Shared Sub Main()
        Dim ServicesToRun() As System.ServiceProcess.ServiceBase

        ' More than one NT Service may run within the same process. To add
        ' another service to this process, change the following line to
        ' create a second service object. For example,
        '
        '   ServicesToRun = New System.ServiceProcess.ServiceBase () {New Service1, New MySecondUserService}
        '
        ServicesToRun = New System.ServiceProcess.ServiceBase () {New Service1}

        System.ServiceProcess.ServiceBase.Run(ServicesToRun)
    End Sub

    'Required by the Component Designer
    Private components As System.ComponentModel.IContainer

    ' NOTE: The following procedure is required by the Component Designer
    ' It can be modified using the Component Designer.  
    ' Do not modify it using the code editor.
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        components = New System.ComponentModel.Container()
        Me.ServiceName = "Service1"
    End Sub

#End Region

    Public folderToWatch As FileSystemWatcher
    Public myDirectory As System.IO.Directory
    Public myFilePath As String
    Public item As String

    Protected Overrides Sub OnStart(ByVal args() As String)
        ' myFilePath = "C:\inetpub\host\forms\bundledPDF"
        myFilePath = "C:\fileTest"
        folderToWatch = New FileSystemWatcher

        With folderToWatch
            .Path = myFilePath
            .Filter = "*.pdf"
            .NotifyFilter = .NotifyFilter
        End With

        AddHandler folderToWatch.Created, AddressOf deleteFiles
        folderToWatch.EnableRaisingEvents = True
    End Sub


    Private Sub deleteFiles(ByVal source As Object, ByVal evt As FileSystemEventArgs)
        ' Loop through all the files in the directory
        myDirectory.SetCurrentDirectory(myFilePath)

        For Each item In myDirectory.GetFiles(myFilePath)
            ' If the file was created 60 min ago or longer
            If File.GetCreationTime(item).AddMinutes(2) < Now() Then
                ' set the file to normal, it may be read only
                File.SetAttributes(item, FileAttributes.Normal)
                ' delete the file
                File.Delete(item)
            End If
        Next
    End Sub

    Protected Overrides Sub OnStop()
        ' Add code here to perform any tear-down necessary to stop your service.
    End Sub

End Class

0
Comment
Question by:bisysweb
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
9 Comments
 
LVL 37

Expert Comment

by:gregoryyoung
ID: 12022383
this might just be because garbage collection has not occurred ... have you tried adding a gc.Collect() just to see if it remedies the proble ? if it does then it just means that the CLR doesnt think it needs to release your memory yet (maybe due to alot of memory being available on the machine)
0
 
LVL 10

Expert Comment

by:prakash_prk
ID: 12024001
0
 

Author Comment

by:bisysweb
ID: 12026855
GregoryYoung - I tried the gc.collect() but nothing.  It sill keeps growing

Prakash prk, I have the framework 1.1
0
Revamp Your Training Process

Drastically shorten your training time with WalkMe's advanced online training solution that Guides your trainees to action.

 
LVL 8

Accepted Solution

by:
wguerram earned 500 total points
ID: 12028495
gregoryyoung can be right about the CLR.

String manipulation increased memory usage in applications.

Try

        Dim MyFiles() As String = System.IO.Directory.GetFiles("C:\")
        For Each item In MyFiles
            ' If the file was created 60 min ago or longer
            If File.GetCreationTime(item).AddMinutes(2) < Now() Then
                ' set the file to normal, it may be read only
                File.SetAttributes(item, FileAttributes.Normal)
                ' delete the file
                File.Delete(item)
            End If
        Next

or
        dim i as integer
        Dim MyFiles() As String = System.IO.Directory.GetFiles("C:\")
        For i = 0 to MyFiles.Length - 1
            ' If the file was created 60 min ago or longer
            If File.GetCreationTime(MyFiles(i)).AddMinutes(2) < Now() Then
                ' set the file to normal, it may be read only
                File.SetAttributes(MyFiles(i), FileAttributes.Normal)
                ' delete the file
                File.Delete(MyFiles(i))
            End If
        Next
0
 

Author Comment

by:bisysweb
ID: 12069461
wguerram, You provided some excelent examples.  I actually put the second one in place, however the leak is still there!  

Could it possibly be someting in my on start?  Is there some way I can provide better information to everyone so that you can better help me troubleshoot this?

0
 

Author Comment

by:bisysweb
ID: 12069560
If the answer to this question can not be found, I am open to figuring out a new way to approach this issue.

I need to delete files 60 min after they are created.  This will be in 1 folder only and will not include sub directories.

A windows service seemed like the ideal solution, but if you can provide any alternatives, I am all ears
0
 
LVL 8

Expert Comment

by:wguerram
ID: 12089416
I tried The GC.Collect:

I try looping through the a list of files calling the getdirectories method.

and printed the name in the debug window.

The first five clicks the memory keeps growing but after that the memory remains the same as the last size.

Try using the GC.Collect after you read all files.

Private Sub deleteFiles(ByVal source As Object, ByVal evt As FileSystemEventArgs)
        ' Loop through all the files in the directory
        myDirectory.SetCurrentDirectory(myFilePath)

        For Each item In myDirectory.GetFiles(myFilePath)
            ' If the file was created 60 min ago or longer
            If File.GetCreationTime(item).AddMinutes(2) < Now() Then
                ' set the file to normal, it may be read only
                File.SetAttributes(item, FileAttributes.Normal)
                ' delete the file
                File.Delete(item)
            End If
        Next
     
       GC.Collect 'gregoryyoung suggestion
    End Sub

0
 
LVL 8

Expert Comment

by:wguerram
ID: 12102294
You could do something else, Make another exe program and add a Sub Main:

Sub Main
 ' Loop through all the files in the directory
        myDirectory.SetCurrentDirectory(myFilePath)

        For Each item In myDirectory.GetFiles(myFilePath)
            ' If the file was created 60 min ago or longer
            If File.GetCreationTime(item).AddMinutes(2) < Now() Then
                ' set the file to normal, it may be read only
                File.SetAttributes(item, FileAttributes.Normal)
                ' delete the file
                File.Delete(item)
            End If
        Next
End sub

'---------------------------

from your service call the program

 Private Sub deleteFiles(ByVal source As Object, ByVal evt As FileSystemEventArgs)
      System.Diagnostics.Process.Start("YourProgram.Exe")
End sub

So after the program finish the loop, memory will be release since it will be closed.
0
 

Expert Comment

by:PHolroyd
ID: 12960444
I don't know if it's relevent but I had similar problems with 'File.Delete' inside a service, only the files didn't even disapear from the directory after the delete.

I tried GC.Collect at the end of whole loop (After I'd processed all the files) and the problem still occured, only after I put the CG.Collect directly after the 'File.Delete' did it work.

Only problem is, I don't know why it worked, and like they say a little knowledge is a dangerous thing.
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This tutorial demonstrates one way to create an application that runs without any Forms but still has a GUI presence via an Icon in the System Tray. The magic lies in Inheriting from the ApplicationContext Class and passing that to Application.Ru…
Well, all of us have seen the multiple EXCEL.EXE's in task manager that won't die even if you call the .close, .dispose methods. Try this method to kill any excels in memory. You can copy the kill function to create a check function and replace the …
In this video, viewers are given an introduction to using the Windows 10 Snipping Tool, how to quickly locate it when it's needed and also how make it always available with a single click of a mouse button, by pinning it to the Desktop Task Bar. Int…
If you’ve ever visited a web page and noticed a cool font that you really liked the look of, but couldn’t figure out which font it was so that you could use it for your own work, then this video is for you! In this Micro Tutorial, you'll learn yo…

617 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