In a windows service I know I have a memory leak. How I know is outside the scope of this question but you can see the initial question here
I have a windows service with some classes:
public partial class VLSService : ServiceBase
{
ReportedContentProcess reportedContent;
protected override void OnStart(string[] args)
{
//when a user reports a video
reportedContent = new ReportedContentProcess();
reportedContent.ProcessTimer.Elapsed += new ElapsedEventHandler(ReportedContentTimer_Elapsed);
}
void ReportedContentTimer_Elapsed(object sender, ElapsedEventArgs e)
{
reportedContent = new ReportedContentProcess();
reportedContent.Process();
reportedContent.ProcessReinstated();
}
}
public class ReportedContentProcess : ProcessBase
{
//location on the library
string libraryArchivedFilePath;
string libraryRealHiFilePath;
string libraryRealLoFilePath;
string libraryFlashHiFilePath;
string libraryFlashLoFilePath;
//location on the reported folder
string reportedContentArchivedFilePath;
string reportedContentRealHiFilePath;
string reportedContentRealLoFilePath;
string reportedContentFlashHiFilePath;
string reportedContentFlashLoFilePath;
string reportedContentFolderPath;
static EmailSettings emailSettings;
/// <summary>
/// This process will move reported content out of the 'real' and 'flash' mounted folders on the
/// hard drive/ storeage location so they cannot under any circumstances be got to by any users
/// of the library.
/// </summary>
public ReportedContentProcess(): base(1021)
{
DirectoryInfo arciveFolderPathInfo = new DirectoryInfo(fileSystemReferencesForService.ArchiveDir);
DirectoryInfo contentFolder = arciveFolderPathInfo.Parent;
reportedContentFolderPath = contentFolder.FullName.ToString() + @"\ReportedContent\";
emailSettings = settingsManagerForService.GetEmailSettings();
}
public override void Process()
{
if (!EnumsAndConstants.ApplicationLocks.ReportedContentProcessRunning)
{
EnumsAndConstants.ApplicationLocks.ReportedContentProcessRunning = true;
videosToProcess = contentManagerForService.GetReportedVideos(false);
//get the reportedvideo object for this video
CreateReportedVideoContentFolder();
ReportedVideo reportedVideo;
foreach (Video v in videosToProcess)
{
string flashVideoExt = string.Empty;
if (v.IsAudio)
{
flashVideoExt = ".mp3";
}
else
{
flashVideoExt = ".mp4";
}
//library location of each file for video
libraryArchivedFilePath = fileSystemReferencesForService.ArchiveDir + v.LocalFile;
libraryRealHiFilePath = fileSystemReferencesForService.RealDir + v.Url.ToString() + "_hi.rm";
libraryRealLoFilePath = fileSystemReferencesForService.RealDir + v.Url.ToString() + "_lo.rm";
libraryFlashHiFilePath = fileSystemReferencesForService.FlashDir + v.Url.ToString() + "_hi" + flashVideoExt;
libraryFlashLoFilePath = fileSystemReferencesForService.FlashDir + v.Url.ToString() + "_lo" + flashVideoExt;
//new location for file to go to
reportedContentArchivedFilePath = reportedContentFolderPath + v.LocalFile;
}
}
/// <summary>
/// A base class that holds all the Global objects for any process that operates under the
/// service. This process works with
/// </summary>
public abstract class ProcessBase
{
public Timer processTimer;
public Timer ProcessTimer{get{ return processTimer;}set{processTimer=value;}}
protected SqlConnection connection;
protected VlsContent contentManagerForService;
protected VlsSecurity securityManagerForService;
protected VlsSettings settingsManagerForService;
protected FileSystemReferences fileSystemReferencesForService;
protected List<Video> videosToProcess;
protected ExeReferences exeReferenecesForService;
protected GeneralSettings generalSettingsForService;
public abstract void Process();
//sets up all the common objects
public ProcessBase()
{
connection = new SqlConnection(ConfigurationManager.ConnectionStrings["Db"].ToString());
contentManagerForService = new VlsContent(connection);
settingsManagerForService = new VlsSettings(connection);
securityManagerForService = new VlsSecurity(connection);
fileSystemReferencesForService = settingsManagerForService.GetFileSystemReferences();
exeReferenecesForService = settingsManagerForService.GetExeReferences();
generalSettingsForService = settingsManagerForService.GetGeneralSettings();
}
//This constructor will call the default constructor ^
protected ProcessBase(long intervalArg) : this()
{
processTimer = new Timer(intervalArg);
processTimer.Enabled = true;
}
}
After profiling this code it seems that this is causing a memory leak. What im wondering is why?
Im thinking that the problematic line is:
reportedContent = new ReportedContentProcess(); [located in the event handler]
But I cant really see why. Surely it will creat pointer in memory called 'reportedContent' then when the above is called it will place actual value on the heap with new values for the members of ReportedContentProcess(). Then when the event handler is run again after about 1 second it will then just replace the GC root pointer 'reportedContent' with a new allocated heap item for the ReportedContentProcess() class. Then the old one (and all of its now abandoned child objects will be garbaged collected as their root is no longer referenced by the call stack..? This should just happen over and over again (out with the old in with the new) style.
Hope some can help I sort of hope this is the problem so I can fix it but want to check before I start re-factoring code.
The profile is here: