I am developing a utility class that contains static methods that will be frequently called by multiple threads. I am noticing that memory use is growing over time, so it seems to me that I have some memory leaks.
Here is a simple example of the pattern I am using for these static methods:
public static int CreateNewThing(int IDofSomeDBObjectHoldingInfoToCreateNewThing)
{
using(SomeDBContext context = new SomeDBContext(connectionString))
{
SomeDBObjectHoldingInfoToCreateNewThing createNewThingyInfo = context.SomeDBObjectsHoldingInfoToCreateNewThing.First(obj => obj.ID == IDofSomeDBObjectHoldingInfoToCreateNewThing);
// Do some stuff to create the new object
// Return the ID of the newly created thingy...
return theNewThingThatWasCreated.ID;
}
}
My question is whether using 'using' statements or directly calling Dispose inside static methods actually clears up any memory. Granted, I haven't stated the overall architecture or purpose of this application, but I am also wondering if I'm using the best pattern here. What are the best practices for creating thread-safe utility classes in .NET?
I am noticing that memory use is growing over time, so it seems to me that I have some memory leaks.
Not necessarily - you'd need to give more data for us to really have a good idea about that.
My question is whether using 'using' statements or directly calling Dispose inside static methods actually clears up any memory.
using statements aren't about cleaning up memory. That's the GC's job. They're about releasing non-memory resources. Whether you're in a static method or not is completely irrelevant to whether the SomeDBContext ought to be disposed or not.
My question is whether using 'using' statements or directly calling Dispose inside static methods actually clears up any memory
using is just a syntactially simpler way of calling Dispose.
using(MyClass obj = new MyClass())
{
}
is just the same as writing:
MyClass obj;
try
{
obj = new MyClass()
}
finally
{
((IDisposable)obj).Dispose();
}
Next, does Dispose free up memory. No, it doesn't. Dispose is designed to release unmanaged resources that won't get cleaned up with then garbage collector releases the memory for this object. It doesn't actually release the memory for the object any quicker. Common things that need to be disposed of are network connections (as is the case here) file handles, unmanaged memory created through interopping with another language, etc.
So, why is your memory going up. In short, it's just the usual behavior. You are creating objects, they are using memory, so your memory is increasing. At some point the garbage collector will determine that it needs to perform a collection to free up some memory. (Possibly because the system is running low and it needs more, possibly because it has just been long enough, or whatever other conditions the C# language has specified. It almost always knows better than you when a collection is really needed.)
So until you have a real problem just don't worry about it, this is normal behavior in a managed language. If you start running out of memory, or having the memory not go down even when collections do occur, then you need to start looking for problems.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With