Solved

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

Posted on 2004-09-09
9
706 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
9 Comments
 
LVL 37

Expert Comment

by:gregoryyoung
Comment Utility
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
Comment Utility
0
 

Author Comment

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

Prakash prk, I have the framework 1.1
0
 
LVL 8

Accepted Solution

by:
wguerram earned 500 total points
Comment Utility
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
Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

 

Author Comment

by:bisysweb
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

Since .Net 2.0, Visual Basic has made it easy to create a splash screen and set it via the "Splash Screen" drop down in the Project Properties.  A splash screen set in this manner is automatically created, displayed and closed by the framework itsel…
Parsing a CSV file is a task that we are confronted with regularly, and although there are a vast number of means to do this, as a newbie, the field can be confusing and the tools can seem complex. A simple solution to parsing a customized CSV fi…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.

744 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

18 Experts available now in Live!

Get 1:1 Help Now