Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 735
  • Last Modified:

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

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
bisysweb
Asked:
bisysweb
1 Solution
 
gregoryyoungCommented:
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
 
bisyswebAuthor Commented:
GregoryYoung - I tried the gc.collect() but nothing.  It sill keeps growing

Prakash prk, I have the framework 1.1
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
wguerramCommented:
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
 
bisyswebAuthor Commented:
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
 
bisyswebAuthor Commented:
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
 
wguerramCommented:
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
 
wguerramCommented:
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
 
PHolroydCommented:
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

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now