我班上有一个static StreamWriter
变量:
private static StreamWriter streamWriter = CreateStreamWriter(pathToFile);
我没有在我的应用中关闭此StreamWriter,因为它需要在应用运行时打开。
如果我多次启动和停止此应用程序,是否会出现内存泄漏?或者关闭应用程序后对象是否正确处理?
此类是ASP.NET MVC 4和WPF应用程序使用的实用程序类。
感谢所有人的回复。这是我添加的代码:
在包含StreamWriter的类中:
public static void OnApplicationExit(object sender, EventArgs e)
{
try
{
streamWriter.Flush();
streamWriter.Close();
streamWriter.Dispose();
}
catch { }
}
public static void OnApplicationExit()
{
try
{
streamWriter.Flush();
streamWriter.Close();
streamWriter.Dispose();
}
catch { }
}
在ASP.NET MVC Global.Asax:
中 protected void Application_End()
{
Utilities.MyClass.OnApplicationExit();
}
答案 0 :(得分:5)
如果我多次启动和停止此应用程序,是否会出现内存泄漏?
没有。当进程结束时,与进程关联的所有资源都将自动返回到操作系统。这是Windows的一个功能;它适用于所有流程,而不仅仅是托管代码流程。
正如其他人所指出的那样,您可能会丢失数据,但您不会泄漏内核对象。
是关闭应用程序后正确处理的对象吗?
不一定。如果应用程序被“快速失败”终止,那么显然没有终结器运行,因为 nothing 运行。如果应用程序被未处理的异常终止,那么它是实现定义的终结器是否运行。
此外,正如Raymond Chen曾经指出的那样,当你知道这个过程被关闭时,运行终结器就像在拆除建筑物之前扫地。这是浪费时间和精力。
简而言之,您不应该依赖终结器来运行程序的正确性。
答案 1 :(得分:4)
当应用程序关闭时,不保证StreamWriter
被处理掉。有时它会,但在某些情况下是不可能的。
没有内存泄漏,因为它使用托管内存。应用程序关闭时将删除整个堆。
它也不是资源泄漏,因为打开文件句柄将在应用程序关闭时关闭。
但是,StreamWriter
有一个缓冲区,如果没有处理,则不会刷新。这意味着您使用编写器编写的最后一些内容可能会从文件中丢失。
答案 2 :(得分:2)
Streamwriter实现IDisposable。因此,如果您不调用其Dispose方法,则无法保证您正确处置其资源。
我认为你有两个基本选择:
保留StreamWriter的静态实例,但在应用程序关闭时捕获,然后调用Streamwriter.Dispose()来释放资源。我不知道您的应用程序是WPF还是Windows窗体应用程序,但如果您可以找到应用程序关闭时触发的事件,您可以在那里调用dispose。我认为Application.ApplicationExit可能就是您所需要的。
将StreamWriter转换为实例变量,使用using语句对其进行实例化,执行IO,然后立即处理它:
using(var writer = new StreamWriter())
{
//do your IO here
}
修改:您表示您的应用是ASP.Net应用。对于ASP.Net应用程序,可以在global.asax的Application_Start事件中创建静态变量,并在global.asax的Application_End事件中处理静态变量。
答案 3 :(得分:1)
当您说“多次启动和停止此应用程序”时,您是说退出流程并且每次都启动一个新流程吗?当进程退出时,操作系统会回收所有内存,因此实际上没有“内存泄漏”。
话虽如此,我觉得在关机时清理资源是个好习惯;您可能决定要在同一进程中重新启动。修复泄漏要比没有泄漏要困难得多。
假设您必须执行其他操作,例如在关闭时刷新写入器。然后,你需要一些在关机时启动的钩子。
答案 4 :(得分:-1)
使用using语句,这是最好的方法。
使用(var r = new StreamWriter(,,)){
}