1

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();
    }
Barka
  • 8,764
  • 15
  • 64
  • 91

5 Answers5

5

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.

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
4

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.

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • So as long as I flush every time after writing to the StreamWriter, I will be in good shape? – Barka Feb 24 '13 at 04:27
  • @user277498: Yes, but it's not considered good practice to leave resources hanging like that. – Guffa Feb 24 '13 at 04:39
  • Thanks! I updated my question with my implementation based on your Answer. Please let me know if you have any additional thoughts. Thanks! – Barka Feb 24 '13 at 07:12
2

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.

svick
  • 236,525
  • 50
  • 385
  • 514
Joe Alfano
  • 10,149
  • 6
  • 29
  • 40
1

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.

seand
  • 5,168
  • 1
  • 24
  • 37
-1

Use the using statement, this is the best way.

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

}

Srikant Krishna
  • 881
  • 6
  • 11
  • How do I use a using statement on a static variable? – Barka Feb 24 '13 at 04:14
  • This is a static variable that needs to be around for the life of the application. I do not want the over head of newing up a new one every time I need to use it. – Barka Feb 24 '13 at 04:16
  • Create it and dispose of it when you are doing the I/O. Well as long as you flush and close you probably shouldn't have any problems, but using is really the best way. – Srikant Krishna Feb 24 '13 at 04:17
  • 1
    The object in the static variable needs to stay alive as long as the application is running. I will at no time close it. The question is: Will the system handle it? – Barka Feb 24 '13 at 04:19
  • Try the Application.ApplicationExit Event. – DasKrümelmonster Feb 24 '13 at 04:22