Question

I have a static StreamWriter variable in my class:

private static StreamWriter streamWriter = CreateStreamWriter(pathToFile);

I am not closing this StreamWriter in my app since it needs to be open while the app is running.

If I start and stop this app many many times, will I get a memory leak? Or is the object disposed of properly upon closing the app?

This class is a utility class used by both ASP.NET MVC 4 and WPF apps.

Thanks to all for your responses. Here is the code I added:

In the class containing the 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 { }
}

And in ASP.NET MVC Global.Asax:

    protected void Application_End()
    {
        Utilities.MyClass.OnApplicationExit();
    }
Was it helpful?

Solution 2

The StreamWriter is not guaranteed to be disposed when the application closes. Sometimes it will, but in some situations that's not possible.

There is no memory leak, as it uses managed memory. The entire heap is removed when the application closes.

It's not a resource leak either, as the open file handles will be closed when the application is shut down.

However, the StreamWriter has a buffer that is not flushed if it's not disposed. That means that the last things that you wrote using the writer may be missing from the file.

OTHER TIPS

If I start and stop this app many many times, will I get a memory leak?

No. All resources associated with a process are automatically returned to the operating system when a process ends. This is a feature of Windows; it is true of all processes, not just managed code processes.

As others have pointed out, you might lose data but you will not leak kernel objects.

is the object disposed of properly upon closing the app?

Not necessarily. If the application is terminated by "failing fast" then obviously no finalizers run because nothing runs. If the application is terminated by an unhandled exception then it is implementation-defined whether finalizers run.

And besides, as Raymond Chen once pointed out, running finalizers when you know the process is being shut down is like sweeping the floors before the building is demolished. It's a waste of time and effort.

In short, you should not rely on finalizers running for the correctness of your program.

Streamwriter implements IDisposable. So if you don't call its Dispose method, you cannot guarentee that you are properly disposing of its resources.

As I see it you have two basic options:

  1. Keep the static instance of the StreamWriter, but catch when you application is shutting down, and then call Streamwriter.Dispose() to release the resources. I don't know if your app is a WPF or Windows Form app, but if you can find an event that fires when the app shuts down, you could call dispose there. I think the Application.ApplicationExit might be what you need.

  2. Convert the StreamWriter to an instance variable, instantiating it with a using statement, do your IO, and then immediately dispose of it:

    using(var writer = new StreamWriter())
    {
        //do your IO here
    }
    

Edit: You indicated that your app is an ASP.Net application. For an ASP.Net application, you can create static variables in the Application_Start event of global.asax and dispose of static variable in the Application_End event of global.asax.

When you say "start and stop this app many many times" do you mean the process exits and you start up a new process every time? When a process exits all its memory is reclaimed by the OS so in practice there's no "memory leak".

Having said this, I do feel it's good practice to clean up resources at shutdown; you might decide that you do want to restart within the same process. It's much harder to fix leaks than to not have them in the first place.

Suppose you have to do something else like flush the writer when upon shutdown. Then, you would need some sort of hook which is kicked off at shutdown.

Use the using statement, this is the best way.

using (var r = new StreamWriter(,,)) {

}

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top