简体   繁体   中英

the relation between resource leaks and Memory leaks and performance

With resource leaks I mean Streams, StreamWriter (I suppose they are consuming File descriptors), Handles (GDI or user also Graphics fonts). Shortly all Closable objects can count as a resource! If there are some resource leaks in the application. Say some InputStreams are not getting closed, are they potential memory leaks too because Garbage Collector is not going to remove them from memory?

Another question: Are resource leaks affecting the performance?

If there are some resource leaks in the application. Say some InputStreams are not getting closed, are they potential memory leaks too because Garbage Collector is not going to remove them from memory?

The GC will clean up resources whether they are closed or not. The only resources which cannot be cleaned up if not shutdown are threads.

When a Stream is discarded without closing, it is closed by the finalizer on a collection. This has two problems

  • exactly when or even if this happens in unpredictable meaning the file might not be flushed or a lock is retained on the file preventing it being deleted.
  • the finalizer is a single thread and closing a resources can take time. If you have enough of these the finalizer won't keep up and you will get an OutOfMemoryError because you have a large number of resources waiting to be cleaned.

It is always better to clean up resources when you have finished with them.

Another question: Are resource leaks affecting the performance?

They can, it depends on how much is leaked. If you don't have much idea you have to assume it a problem unless you are confident it is not. eg a program could leak one 24 bytes object once per day, or it could leak 100 MB per seconds. Not all leaks are the same.

Memory leak , by definition is a memory that is useless, but still allocated in your proess space. Considering that CLR process on 32bit machine has approximately 1.2GB of possible memory, I would say it's extremely dangerous to have a memory leaks in your application.

Naturally, everything depends on how big, mission critical + other factors yuor application is. But, in any case, always try to avoid them, especially if you already know that they are exist and especially if you already know where they are.

EDIT

The resource leaks are the same story actually. Resource allocates the memory, so the leak of it creates a memory leak, by definition.

Hope this helps.

It depends on what you call performance. I'll assume you're speaking of overall performance, meaning that memory consumption, speed, and the like are all important.

It depends, too, on the resource used. Some resources (eg file handles) are recovered when the process exits, so the leak will only be a problem when executing. Others (like server or database connections) could remain leaking even after your application execution. Others (like mutexes, etc.) should be released as soon as possible.

Now, the consequences depend on the resource. If the resource is a native object in the same process, then leaking it will probably leak the associated memory. If the resource is a mutex you locked but failed to unlock, then you are probably about to deadlock your application. If the resource is a connection, the server will keep that connection open even after you stopped using it. If the resource is a file, it could stop other applications (or even your own application) to access it again.

In the end, while some resources could be leaked, other shouldn't. As far as I am concerned, no resource should be leaked, ever, but YMMV.

So you should make an habit of always correctly releasing the resources you acquired (memory, files, connections, mutexes, etc.), no matter the perceived importance of that resource. Doing so will train you in the right coding patterns (and mindset).

RAII and Exception Safety are the keyword you're searching for if you want to explore the notions.

For C#, the Dispose pattern (IDisposable interface, and the finalizer) and the using keyword will be needed. Another solution is to use the finally class of a try / finally to free your resource, but this is difficult to maintain correctly.

In Java, you'll need Java 7 (IIRC), and use the AutoCloseable interface and the " try-with-resources " statement. As in C#, you can use the finally class of a try / finally to free your resource, with the same problems.

Yes, memory leaks means that the app needs to run the Garbage collector more often and is able yto recover less memory on each run. When the memory is exausted, the application will crash.

Files not getting closed will lead to a the app being unable to do anything related to files or sockets when the maximum number of open files is reached, which usually makes the application unusable.

Leak can occur when you keep a rooted reference to an unused object. The GC is unable to collect it as it is still reachable. Pay special attention to your static instances and event handlers attached to static events.

When you leave a disposable object undiposed, in most case it will defer the release of unmanaged resources and may cause bug (Stream not flushed, ...). When releasing memory, the garbage collector calls a Finalizer on objects containing unmanaged resources. This is more expensive than a staight call to Dispose that will lessen GC's job. It is unpredictable, the finalizer may be called really lately. So if you do not call Dispose it can lead to temporary resource starvation (no remaining file handle, ...).

So there is no memory leak for not calling Dispose on this Stream but you shouldn't rely on Finalization as it is costly and unpredictable. Moreover Dispose can do more than releasing resources, it can also properly clear a managed object (flush buffered stream, ...).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM