How to ensure memory leak in the following case

If the class has a property that contains unmanaged resources. How to make sure memory leak when using class

Class A { B {get; set;} } 

B contains unmanaged resources.

+4
source share
4 answers

Add IDisposable and clear the unmanaged resources by calling Dispose() , preferably by placing the Dispose call in the finally statement to clear the resources even in the event of an exception.

C # has a using keyword that can be used to make sure that the Dispose method is called, even if an exception is thrown.

EDIT: Combined call to GC.SuppressFinalize and finalizer implementation for Ran response

 class A : IDisposable { private bool _disposed; ~A() { this.Dispose(false); } public void Dispose() { this.Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (!_disposed) { if (disposing) { // dispose managed resources } // clean up unmanaged resources _disposed = true; } } } class Program { static void Main(string[] args) { using (var someInstance = new A()) { // do some things with the class. // once the using block completes, Dispose // someInstance.Dispose() will automatically // be called } } } 
+7
source

Using IDisposable may not be enough, because it relies on a user who wants to call Dispose or use using , etc.

For a complete solution, combine IDisposable and a finalizer. Like this:

Edit: Some corrections have been made to the Dispose method based on the SpeksETC comment.

 class MyClass : IDisposable { ~MyClass() { Dispose(false); } public void Dispose() { GC.SupressFinalize(); Dispose(true); } protected virtual void Dispose(bool disposing) { if (!disposing) { // clear unmanaged resources here (can only be called once) ... } // dispose called explicitly by the user, clean up managed resources here ... } } 

This ensures that internal resources are always cleared, even if the user forgot to call Dispose , but at the same time allows the user to quickly clear the resources.

An if required inside the Dispose implementation, because if this class terminates, you can not call Dispose for your members, because they have already been GC'ed already.

+4
source

I think itโ€™s important to note that B is a managed resource that contains unmanaged resources.

Therefore, A must implement IDisposable and dispose B in its Dispose () method, but does not need a finalizer, since it does not have unmanaged resources for cleaning - the finalizer must be implemented inside B. Even if you implemented the finalizer, it is called Dispose, which looks like that:

 protected virtual void Dispose(bool disposing) { if (disposing) { // dispose called explicitly by the user, clean up managed resources here b.Dispose() } // no unmanaged resources to clean up so do nothing which makes Finalizer unneccesary ... } 
+1
source

SpeksEtc is true in the sense that if B contains unmanaged resources, then B must guarantee no leaks, not A.

But what are unmanaged resources and will the SafeHandle class help? Then B will contain SafeHandle, which will contain an unmanaged resource, and you will not need to worry about it.

0
source

All Articles