memory leak
when tried to stress test the proxy, the memory used grow up and remain high when the test ended... couldn't find the root cause :(
Did you tried to check it with a memory profiler?
yes... but couldn't find the reason
If you would post the code you used for stress test we could see if the leak is actually from your code or from TWP. Sometimes, it could be from user code.
I think when we get a chance in future, we should do the dispose pattern throughout this project. Not that I am aware of a memory leak, but if we unknowingly fail to call dispose in some place, by following dispose pattern it will be atleast safe, because dispose will be eventually called from object destructor.
I am still not 100% sure if this approach is perfect.
https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/implementing-dispose https://stackoverflow.com/questions/151051/when-should-i-use-gc-suppressfinalize
public class MyClass : IDisposable
{
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
disposed = true;
if (disposing)
{
// Set large managed objects like StringBuilder, List etc to null
...
}
// call Dispose() on objects that implement IDisposable and any unmanaged resources
ourClass.Dispose();
stream.Dispose();
tcpClient.Dispose();
...
}
}
public void Dispose()
{
Dispose(true);
// need to suppress expensive finalize call when Dispose() is called properly
GC.SuppressFinalize(this);
}
~MyClass()
{
// as a safety net if we failed calling Dispose() somehow due to an unidentified bug
Dispose(false);
}
}
please do not implement destructors unless the class needs to free some unmanaged resource. doing so causes the objects to be queued up for finalization rather than immediately freed by the garbage collector and decreases performance.
https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/finalizers "Empty finalizers should not be used. When a class contains a finalizer, an entry is created in the Finalize queue. This queue is processed the garbage collector. When the GC processes the queue, it calls each finalizer. Unnecessary finalizers, including empty finalizers, finalizers that only call the base class finalizer, or finalizers that only call conditionally emitted methods cause a needless loss of performance."
also i believe you also should not call Dispose() from the finalizer thread.
https://docs.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqldatareader.close?redirectedfrom=MSDN&view=netframework-4.8#System_Data_SqlClient_SqlDataReader_Close
Caution Do not call Close or Dispose on a Connection, a DataReader, or any other managed object in the Finalize method of your class. In a finalizer, you should only release unmanaged resources that your class owns directly. If your class does not own any unmanaged resources, do not include a Finalize method in your class definition. For more information, see Garbage Collection.
please do not implement destructors unless the class needs to free some unmanaged resource. doing so causes the objects to be queued up for finalization rather than immediately freed by the garbage collector and decreases performance.
yes, you are right, but in TWP the finalizers should not be called. It it is called, then it is a bug. I added a breakpoint in debug mode, so it it stops there, then we will fix it. It did not stopped, yet.