В службе Windows я знаю, что у меня утечка памяти.Насколько я знаю, это выходит за рамки этого вопроса, но вы можете увидеть начальный вопрос здесь
У меня есть служба Windows с некоторыми классами:
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;
}
}
После профилирования этого кода кажется, что это вызывает утечку памяти.Что мне интересно, почему?
Я думаю, что проблемная строка такова:
reportedContent = new ReportedContentProcess(); [located in the event handler]
Но я не могу понять, почему.Конечно, он создаст указатель в памяти с именем «connectedContent», затем при вызове вышеизложенного фактическое значение будет помещено в кучу с новыми значениями для членов ReportedContentProcess ().Затем, когда обработчик событий снова запустится примерно через 1 секунду, он просто заменит корневой указатель GC «reportContent» новым выделенным элементом кучи для класса ReportedContentProcess ().Затем старый (и все его теперь заброшенные дочерние объекты будут собраны, так как на их корень больше не ссылается стек вызовов). Это должно происходить снова и снова (со старым и новым).
Надеюсь, что кто-то может помочь. Я надеюсь, что это проблема, поэтому я могу ее исправить, но хочу проверить, прежде чем начать перефакторинг кода.
Профиль здесь: