Disposing MemoryCache in Finalizer throws AccessViolationException - c#

EDIT
See edit note at the bottom of the question for additional detail.
Original question
I have a CacheWrapper class which creates and holds onto an instance of the .NET MemoryCache class internally.
MemoryCache hooks itself into AppDomain events, so it will never be garbage-collected unless it is explicitly disposed. You can verify this with the following code:
Func<bool, WeakReference> create = disposed => {
var cache = new MemoryCache("my cache");
if (disposed) { cache.Dispose(); }
return new WeakReference(cache);
};
// with false, we loop forever. With true, we exit
var weakCache = create(false);
while (weakCache.IsAlive)
{
"Still waiting...".Dump();
Thread.Sleep(1000);
GC.Collect();
GC.WaitForPendingFinalizers();
}
"Cleaned up!".Dump();
Because of the behavior, I believe that my MemoryCache instance should be treated as an unmanaged resource. In other words, I should ensure that it is disposed in the finalizer of CacheWrapper (CacheWrapper is itself Disposable follows the standard Dispose(bool) pattern).
However, I am finding that this causes issues when my code runs as part of an ASP.NET app. When the application domain is unloaded, the finalizer runs on my CacheWrapper class. This in turn attempts to dispose the MemoryCache instance. This is where I run into issues. It seems that Dispose attempts to load some configuration information from IIS, which fails (presumably because I'm in the midst of unloading the app domain, but I'm not sure. Here's the stack dump I have:
MANAGED_STACK:
SP IP Function
000000298835E6D0 0000000000000001 System_Web!System.Web.Hosting.UnsafeIISMethods.MgdGetSiteNameFromId(IntPtr, UInt32, IntPtr ByRef, Int32 ByRef)+0x2
000000298835E7B0 000007F7C56C7F2F System_Web!System.Web.Configuration.ProcessHostConfigUtils.GetSiteNameFromId(UInt32)+0x7f
000000298835E810 000007F7C56DCB68 System_Web!System.Web.Configuration.ProcessHostMapPath.MapPathCaching(System.String, System.Web.VirtualPath)+0x2a8
000000298835E8C0 000007F7C5B9FD52 System_Web!System.Web.Hosting.HostingEnvironment.MapPathActual(System.Web.VirtualPath, Boolean)+0x142
000000298835E940 000007F7C5B9FABB System_Web!System.Web.CachedPathData.GetPhysicalPath(System.Web.VirtualPath)+0x2b
000000298835E9A0 000007F7C5B99E9E System_Web!System.Web.CachedPathData.GetConfigPathData(System.String)+0x2ce
000000298835EB00 000007F7C5B99E19 System_Web!System.Web.CachedPathData.GetConfigPathData(System.String)+0x249
000000298835EC60 000007F7C5BB008D System_Web!System.Web.Configuration.HttpConfigurationSystem.GetApplicationSection(System.String)+0x1d
000000298835EC90 000007F7C5BAFDD6 System_Configuration!System.Configuration.ConfigurationManager.GetSection(System.String)+0x56
000000298835ECC0 000007F7C63A11AE System_Runtime_Caching!Unknown+0x3e
000000298835ED20 000007F7C63A1115 System_Runtime_Caching!Unknown+0x75
000000298835ED60 000007F7C639C3C5 System_Runtime_Caching!Unknown+0xe5
000000298835EDD0 000007F7C7628D86 System_Runtime_Caching!Unknown+0x86
// my code here
Is there any known solution to this? Am I correct in thinking that I do need to dispose the MemoryCache in the finalizer?
EDIT
This article validates Dan Bryant's answer and discusses many of the interesting details. In particular, he covers the case of StreamWriter, which faces a similar scenario to mine because it wants to flush it's buffers upon disposal. Here's what the article says:
Generally speaking, finalizers may not access managed objects.
However, support for shutdown logic is necessary for
reasonably-complex software. The Windows.Forms namespace handles this
with Application.Exit, which initiates an orderly shutdown. When
designing library components, it is helpful to have a way of
supporting shutdown logic integrated with the existing
logically-similar IDisposable (this avoids having to define an
IShutdownable interface without any built-in language support). This
is usually done by supporting orderly shutdown when
IDisposable.Dispose is invoked, and an abortive shutdown when it is
not. It would be even better if the finalizer could be used to do an
orderly shutdown whenever possible.
Microsoft came up against this problem, too. The StreamWriter class
owns a Stream object; StreamWriter.Close will flush its buffers and
then call Stream.Close. However, if a StreamWriter was not closed, its
finalizer cannot flush its buffers. Microsoft "solved" this problem by
not giving StreamWriter a finalizer, hoping that programmers will
notice the missing data and deduce their error. This is a perfect
example of the need for shutdown logic.
All that said, I think that it should be possible to implement "managed finalization" using WeakReference. Basically, have your class register a WeakReference to itself and a finalize action with some queue when the object is created. The queue is then monitored by a background thread or timer which calls the appropriate action when it's paired WeakReference gets collected. Of course, you'd have to be careful that your finalize action doesn't inadvertantly hold onto the class itself, thus preventing collection altogether!

You can't Dispose managed objects in the finalizer, as they might have already been finalized (or, as you've seen here, portions of the environment may no longer be in the state you're expecting.) This means that if you contain a class which must be Disposed explicitly, your class must also be Disposed explicitly. There's no way to 'cheat' and make the Disposal automatic. Unfortunately, garbage collection is, in cases like this, a leaky abstraction.

I would suggest that objects with finalizers should generally not be exposed to the outside world, and should only hold strong references to things which are actually needed for finalization and are not exposed to anything in the outside world that is not expecting them to be used for that purpose. Public-facing types should not have finalizers themselves, but should instead encapsulate cleanup logic within privately-held instances of finalizable classes whose purpose is to encapsulate such logic.
The only time it really makes sense for a finalizer to attempt to clean up a resource which is owned by another object is when the other object is designed to interface with the finalizer. I can't think of any places where Framework classes have engineered in the proper hooks, but will offer an example how Microsoft could have engineered them to do so.
A File object could offer an event with thread-safe subscribe and unsubscribe methods which would fire (notifying the last subscriber first) when the File object receives either a Dispose call or a finalize request. The event would fire between the time Finalize is called and the time the encapsulated file is actually closed, and could be used by a an external buffering class as a signal that it needs to give the File any information which it has received but not yet passed along.
Note that to make such a thing work properly and safely, it would be necessary that the part of the File object which has the finalizer not be exposed to the public, and that it use a long weak reference to ensure that if it runs while the public-facing object is still alive, it will reregister itself for finalization. Note that if the only reference to a WeakReference object is stored in a finalizable object, its Target property may be invalidated if the finalizable object becomes eligible for finalization even if the actual target of the reference is still alive. Defective design, IMHO, and one which must be worked around somewhat carefully.
It's possible to design objects with finalizers that can cooperate (the easiest way to do it, generally, is to only have one object in the group sport a finalizer), but if things aren't designed to cooperate with finalizers, the best that one can do is generally have a finalizer sound an alarm indicating "This object wasn't supposed to be Disposed but wasn't; because it wasn't, resources are going to leak, and there's nothing to be done about it except fix the code to dispose the object properly in future".

Related

Are destructor methods used implicitly by the garbage collector, and dispose methods used by developers to explicitly dispose of objects?

I can see there's already a lot of threads regarding dispose vs. destructor methods but I just want to make sure that I'm understanding them correctly before I move on.
Are destructor methods used implicitly by the garbage collector for when objects are no longer referenced (i.e. no longer needed) and dispose methods used by us developers to explicitly dispose of objects that may not be handled by the garbage collector?
Also - I'm reading into all this now and it seems that it's a case of one or the other with these methods. So for example given the following code:
class DansClass : IDisposable
{
public void Dispose()
{
GC.SuppressFinalize(this);
Console.WriteLine("Disposing...");
}
-DansClass()
{
Console.WriteLine("Destructing...");
}
}
The output will be:
Destructing...
Understandable, as we've suppressed the finalize (destructor) so we only see the Dispose output.
But if I comment out the SuppressFinalize() method the output is:
Disposing...
Why isn't the destructor called as well?
Well the behavior you're seeing is because Finalizers (what you're refering to as a Destructor is also known as a Finalizer in .Net) are queued up to run in the background by the Garbage Collector.
Eventually it will be called (although in some instances it may not). You can force their execution, however, to understand what is going on:
// Assuming you remove the GC.SuppressFinalize call
myDisposable.Dispose();
GC.WaitForPendingFinalizers();
// Output:
// Disposing...
// Destructing...
You only need to implement the pattern when you have external resources, or encapsulate members which contain external resources. Finalizers should only be implemented when you have external, unmanaged resources.
Proper implementation of the IDisposable pattern requires:
Dispose cleans up both unmanaged and managed resources
Finalizer cleans up hanging, unmanaged resources (if none exist, it is not needed)
Neither may throw an exception, Dispose must be callable more than once
The Finalizer should call the Dispose implementation
Domain specific termination methods, like Close, should be functionally equivalent to Dispose if both exist
Dispose methods, finalizers, and C#'s ironically-named destructors, exist because many objects ask other entities to do things on their behalf until further notice (typically granting exclusive use of something like a file, a region of memory, communications stream, hardware device, GDI handle, etc.); if an object issuing such a request were to disappear without those other entities know their services are no longer required, anything that had been set aside on behalf of the abandoned object would remain uselessly inaccessible.
The IDisposable.Dispose method provides a nice consistent way of telling an object that it will no longer be asked to do anything would require the assistance of other entities, and that any other entities which were doing anything on its behalf should be told to stop doing so. If IDisposable.Dispose is called properly, objects can minimize the extent to which outside entities have to act on their behalf.
Unfortunately, for various reasons (most being easily avoidable; some not), objects are sometimes abandoned without IDisposable.Dispose having been called. This will result in outside entities having to uselessly keep acting, at least for awhile, on behalf of the objects which are abandoned. To avoid having outside entities act forever on behalf of outside entities, the system can notify objects that they have been abandoned, thus giving them a chance to inform outside entities of this fact. Whenever an object whose class overrides Object.Finalize is created, it will be placed in a special list of objects that want to be notified if they are abandoned. Existence on this list, by itself, is not enough to make an object be considered "live", but before the garbage collector removes dead objects from memory it will check whether they are on the notify-before-destruction list. All dead objects which are on the list will be moved from the list of objects requesting notification if/when they are abandoned to a list of objects needing to be notified that they have been abandoned. Placement on this second list will cause the dead objects, and any objects to which they hold references, to be considered "alive" again, at least until the notification has been performed. When they are moved to the second list, however, they are removed from the first list so that if they are later found to be dead again, they will be swept from memory without further notice.
After the garbage collection completes, if any objects are in the list of objects needing to be notified of abandonment, the system will call the Object.Finalize method of each such object. Typically, once Object.Finalize has been called on such an object, there won't be any more rooted references to it and it will vanish on the next garbage collection. It is possible, however, for objects to be resurrected.
In vb.net and, so far as I know, most .net languages, one overrides Object.Finalize by simply declaring an override in the usual fashion. For whatever reason, the creators of C# decided to forbid that. Instead, in C#, one must use a language structure, ironically called a "Destructor", to override Finalize so that objects which are found to be abandoned will not be destroyed without notice, but instead be given a chance to clean up.
There are many tricky wrinkles in the actual operation of Object.Finalize, and it is best to avoid relying upon it except when absolutely necessary. The ironically-named "destructors" don't actually destroy objects, but rather delay their destruction. Calling GC.SuppressFinalize() on an object will remove it from the list of objects requesting notification when they are abandoned; provided that Dispose is called on an object, and it in turn calls GC.SuppressFinalize() as its last operation, there isn't any particular harm in having an object override Finalize or declare a "destructor", but in general it's best to only override Finalize (or declare "destructors") in relatively simple classes.

When should I create a destructor?

For example:
public class Person
{
public Person()
{
}
~Person()
{
}
}
When should I manually create a destructor?
When have you needed to create a destructor?
UPDATE: This question was the subject of my blog in May of 2015. Thanks for the great question! See the blog for a long list of falsehoods that people commonly believe about finalization.
When should I manually create a destructor?
Almost never.
Typically one only creates a destructor when your class is holding on to some expensive unmanaged resource that must be cleaned up when the object goes away. It is better to use the disposable pattern to ensure that the resource is cleaned up. A destructor is then essentially an assurance that if the consumer of your object forgets to dispose it, the resource still gets cleaned up eventually. (Maybe.)
If you make a destructor be extremely careful and understand how the garbage collector works. Destructors are really weird:
They don't run on your thread; they run on their own thread. Don't cause deadlocks!
An unhandled exception thrown from a destructor is bad news. It's on its own thread; who is going to catch it?
A destructor may be called on an object after the constructor starts but before the constructor finishes. A properly written destructor will not rely on invariants established in the constructor.
A destructor can "resurrect" an object, making a dead object alive again. That's really weird. Don't do it.
A destructor might never run; you can't rely on the object ever being scheduled for finalization. It probably will be, but that's not a guarantee.
Almost nothing that is normally true is true in a destructor. Be really, really careful. Writing a correct destructor is very difficult.
When have you needed to create a destructor?
When testing the part of the compiler that handles destructors. I've never needed to do so in production code. I seldom write objects that manipulate unmanaged resources.
It's called a "finalizer", and you should usually only create one for a class whose state (i.e.: fields) include unmanaged resources (i.e.: pointers to handles retrieved via p/invoke calls). However, in .NET 2.0 and later, there's actually a better way to deal with clean-up of unmanaged resources: SafeHandle. Given this, you should pretty much never need to write a finalizer again.
You don't need one unless your class maintains unmanaged resources like Windows file handles.
It's called a destructor/finalizer, and is usually created when implementing the Disposed pattern.
It's a fallback solution when the user of your class forgets to call Dispose, to make sure that (eventually) your resources gets released, but you do not have any guarantee as to when the destructor is called.
In this Stack Overflow question, the accepted answer correctly shows how to implement the dispose pattern. This is only needed if your class contain any unhandeled resources that the garbage collector does not manage to clean up itself.
A good practice is to not implement a finalizer without also giving the user of the class the possibility to manually Disposing the object to free the resources right away.
I have used a destructor (for debug purposes only) to see if an object was being purged from memory in the scope of a WPF application. I was unsure if garbage collection was truly purging the object from memory, and this was a good way to verify.
When you have unmanaged resources and you need to make sure they will be cleaned up when your object goes away. Good example would be COM objects or File Handlers.
Destructors provide an implicit way of freeing unmanaged resources encapsulated in your class, they get called when the GC gets around to it and they implicitly call the Finalize method of the base class. If you're using a lot of unmanaged resources it is better to provide an explicit way of freeing those resources via the IDisposable interface. See the C# programming guide: http://msdn.microsoft.com/en-us/library/66x5fx1b.aspx
Answer:
When you have to release unmanaged resources, like file handles, database connections, etc.
// Example
public class Person
{
private FileStream _fileStream;
public Person()
{
_fileStream = new FileStream("test.txt", FileMode.Open);
}
~Person()
{
_fileStream.Close();
}
}
Explanation:
The destructor is called when the object is garbage collected. It is not called when the object is destroyed by the programmer. It is called when the object is no longer referenced by any other object. It is called when the object is no longer in scope. It is called when the object is no longer in memory.

IDisposable with destructor: requires thread-safe implementation?

This is pretty much only for me to make sure, I got this right:
We have a large resource class implementing the IDisposal pattern. It should (by design) be implemented in a way, that enables it to get called more than one time (even if we try to call it exactly one time of course). We also implement a finalizer, which also calls the Dispose() method - just as backup. If called manually, Dispose() will also call GC.SuppressFinalize(this).
There are several examples of disposal patterns around. Most of them call GC.SuppressFinalize(this) at the end of the disposing code. Some claim, it would be better, to call it at the beginning of the Dispose() method, before any cleaning. Latter argue, this would make sure, the GC doesn't call the finalizer concurrently, while we are still cleaning up.
Question:
It seems, placing GC.SuppressFinalize at the beginning doesn't do any better? We still have a race condition, right? So is it true, that we rather should implement Dispose() in a thread safe way instead?
The GC only cleans up objects that are not 'reachable'.
A class in which code is executing is still 'reachable' because it's this pointer is on the stack. So while dispose is executing, the finalizer won't be called.
So it does not matter if you call SuppressFinalize at the begin or end.
As commentors below indicated, the CLR implementation does not appear to guarantee that your object does not get garbage collected/finalized while instance methods are executing. The only possible 'dependable' reference keeping the object alive is the one used to invoke the method on the object, but I don't know enough about the JIT internals to make statements about that, and it's behaviour might change.
I'm leaving the answer here for access to the discussion below.
While it is sometimes possible for an object to be finalized while a seemingly-live reference exists, that can only happen when nothing else is going to ever refer to the object. The GC.SuppressFinalize(this) actively refers to the present object 'this', thus guaranteeing that it will not be finalized until the GC.SuppressFinalize executes. Further, the fact that the object reference existed to dispose the object, and was available to the Dispose method, guarantees that the finalizer couldn't have been queued before Dispose started running unless the object was dead and a finalizer somewhere (either its own finalizer, or that of some other object) resurrected it.
Because there are some scenarios where an object could be scheduled for finalization and resurrected without ever being aware of it, it may not be a bad idea to protect a dispose and finalize against redundant operation. Microsoft's pattern is not a good one, however. Finalizable objects shouldn't hold references to any objects not needed for finalization. If an object would hold a mixture of managed and unmanaged resources, the unmanaged resources should be moved into their own classes (effectively turning them into managed resources), so then the main object would hold nothing but managed resources.
Dispose should not throw any exceptions.
I would make sure all the code in Dispose is thread safe so that if it gets called it will not do anything strange. Usually adding checks if variables are null already should do the trick.
In the microsoft examples i've only seen GC.SuppressFinalize at the end of the Dispose function.

The cost of finalize in .Net

(1) I've read a lot of questions about IDisposable where the answers recommend not using Finalize unless you really need to because of the process time involved.
What I haven't seen is how much this cost is and how often it's paid. Every millisecond? second? hour, day etc.
(2) Also, it seems to me that Finalize is handy when its not always known if an object can be disposed. For instance, the framework font class. A control can't dispose of it because it doesn't know if the font is shared. The font is usually created at design time so the user won't know to dispose it, therefore finalize kicks in to finally get rid of it when there are no references left. Is that a correct impression?
The main problem with finalize is that it blocks an object from being garbage collected. Instead, the finalizer is called, and the object collected "on the next run". Well, technically IIRC the finalizer runs a list of objects in a separate thread. Anyhow, this is not an "every ms" issue, more an "multiple GC runs needed to get rid of the objects.
Finalize is conceptually different than Dispose. Finalize can only free unmanaged resources. Dispose can free managed and unmanaged resources. You should use each as appropriate. (Note that a class with a Finalizer should always implement IDisposable).
Dispose must be called explicitly; Finalize can only be called by the GC.
Update: See my blog post on How to Implement IDisposable and Finalizers: 3 Easy Rules.
I've got a blog post about IDisposable and Finalizing - not about the performance though.
I'll answer your second question.
No, Finalize should not be used in this manner. In fact, with the exception of only a very few fringe cases, you should only override Finalize (or declare a destructor in C#) if the class directly holds unmanaged resources.
The issue you described is one of ownership. The owner of an IDisposable class is responsible for its lifetime and the decision of when to call Dispose. Other parts of code are free to use that class, but since they cannot claim ownership they should not participate in the lifetime management of that class.
Unfortunately I am not very familiar with the Font class nor how it might relate to the specific scenario that was the impetus for your question, but I can make a general statement that might apply to you. If your code did not create the instance (via the constructor) directly then your code should not be considered the owner. In that case you can assume the responsibility for disposal is left to something else.
Finalize is extremely useful as a double check. If a crash or someone's bad code doesn't dispose your object before it goes out of scope, guarantee that its resources will be released in the finalizer.
You can do some fancy footwork in your disposer though by calling GC.SuppressFinalize(this) which will allow you to write a method which will work in both situations and give you a guarantee that the code will work nicely.
You could even fire an MDA if you were writing a framework to remind people that they should dispose your object.
The penalty of the finalizer is basically that you end up pushing your object into the level 2 queue which takes longer to run. If you are consistently using objects and they are finalizing this could result in a level 2 collection running more often than neccessary just to run your finalizer threads.

Singleton with finalizer but not IDisposable

This is what I understand about IDisposable and finalizers from "CLR via C#", "Effective C#" and other resources:
IDisposable is for cleaning up managed and unmanaged resources deterministically.
Classes that are responsible for unmanaged resources (e.g. file handles) should implement IDisposable and provide a finalizer to guarantee that they are cleaned up even if the client code does not call Dispose() on the instance.
Classes that are responsible for managed resources only should never implement a finalizer.
If you have a finalizer then you must implement IDisposable (this allows client code to do the right thing and call Dispose(), while the finalizer prevents leaking resources if they forget).
While I understand the reasoning for and agree with all of the above, there is one scenario where I think it makes sense to break these rules: a singleton class that is responsible for unmanaged resources (such as providing a single point of access to particular files).
I believe it is always wrong to have a Dispose() method on a singleton because the singleton instance should live for the life of the application and if any client code calls Dispose() then you are stuffed. However, you want a finalizer so that when the application is unloaded the finalizer can clean up the unmanaged resources.
So having a singleton class with a finalizer that does not implement IDisposable seems to me to be a reasonable thing to do, yet this type of design is counter to what I understand are best practices.
Is this a reasonable approach? If not, why not and what are the superior alternatives?
I'd first mention that Object Oriented design patterns and their consequences do not always influence every language decision, even in Object Oriented languages. You can certainly find classic design patterns that are easier to implement in one language (Smalltalk) as opposed to another (C++).
That being said, I'm not sure I agree with the premise that a singleton instance should only be disposed at the end of an application. Nothing in the design pattern descriptions that I've read for Singleton (or Design Patterns: Elements of reusable Object-Oriented Software) mention this as a property of this pattern. A singleton should ensure that only one instance of the class exists at any one moment in time; that does not imply that it must exist for as long as the application exists.
I have a feeling that in practice, many singletons do exist for most of the life of an application. However, consider an application that uses a TCP connection to communicate with a server, but can also exist in a disconnected mode. When connected, you would want a singleton to maintain the connection information and state of the connection. Once disconnected, you may want to keep that same singleton - or you may dispose of the singleton. While some may argue that it makes more sense to keep the singleton (and I may even be among them), there is nothing in the design pattern itself that precludes you from disposing of it - if a connection is remade, the singleton can be instantiated again, as no instance of it exists at that moment in time.
In other words, you can create scenarios where it is logical for singletons to have IDisposable.
If the unmanaged resource is released only on application exit you don't even need to worry with a finalizer since the process unload should deal with this for you anyway.
If you have multiple app domains and you want to deal with an app domain unload that's one possible issue but possibly one you don't need to care about.
I second those saying that this design is possibly not the right thing to do (and will make it harder to fix is subsequently you find that you do actually need two instances)
Create the object (or a lazy loading wrapper object) in your entry point and pass it through the code to where it is needed making it clear who is responsible for providing it to whom, then you are free to change the decision to use only one with little effect to the rest of the code (which uses what it gets given)
As long as your finalizer doesn't call methods (such as Dispose) on any other managed objects, you should be fine. Just remember that finalization order is not deterministic. That is, if your singleton object Foo holds a reference to object Bar that requires disposal, you cannot reliably write:
~Foo()
{
Bar.Dispose();
}
The garbage collector might have collected Bar already.
At the risk of stepping into a pile of OO goo (i.e. starting a war), one alternative to using a singleton is to use a static class.
While it may get you code review gripes and FxCop warnings, there's nothing intrinsically wrong with implementing a finalizer without IDisposable. However, doing so on a singleton is not a reliable way to capture process or AppDomain tear-down.
At the risk of offering subjective design advice: If the object is truly stateless, make it a static class. If it is stateful, question why it is a Singleton: you're creating a mutable global variable. If you're trying to capture application close, deal with it when your main loop exits.
Applicability of Singleton to any particular situation aside,
I think there is nothing wrong with Disposing of Singleton. In combination with lazy instantiation it just means that you release resource if you do not need it temporarily, and then re-acquire it as needed.
If you want to create a singleton with a finalizer, you should probably have the static reference to it be a WeakReference. This will require a little bit of extra work to ensure thread-safety in the accessor, but it will allow the singleton to be garbage-collected when nobody is using it (if someone subsequently calls the GetInstance() method, they'll get a new instance). If a static strong reference were used, it would keep the singleton instance alive even if there were no other references to it.

Categories