Solved

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

Posted on 2004-09-09
9
714 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
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
Optimizing Cloud Backup for Low Bandwidth

With cloud storage prices going down a growing number of SMBs start to use it for backup storage. Unfortunately, business data volume rarely fits the average Internet speed. This article provides an overview of main Internet speed challenges and reveals backup best practices.

 
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

VMware Disaster Recovery and Data Protection

In this expert guide, you’ll learn about the components of a Modern Data Center. You will use cases for the value-added capabilities of Veeam®, including combining backup and replication for VMware disaster recovery and using replication for data center migration.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Call windows 10 virtual keyboard from windows forms app 2 36
Import a txt file into a DataGridView and TextBox 20 38
Store results in vb.net 3 22
VB.NET 2008 Publish Error 2 27
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…
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.
Along with being a a promotional video for my three-day Annielytics Dashboard Seminor, this Micro Tutorial is an intro to Google Analytics API data.
In a recent question (https://www.experts-exchange.com/questions/28997919/Pagination-in-Adobe-Acrobat.html) here at Experts Exchange, a member asked how to add page numbers to a PDF file using Adobe Acrobat XI Pro. This short video Micro Tutorial sh…

803 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