Please see code below. The destructors are never called. Anyone know why and how this can be rectified?
public partial class Form1 : Form
{
private Goo goo;
public Form1()
{
InitializeComponent();
goo = Goo.GetInstance();
}
}
public class Goo
{
private foo f = new foo();
private static Goo goo;
private Goo()
{}
public static Goo GetInstance()
{
if(goo!=null)
{
goo = new Goo();
}
return goo;
}
~Goo()
{
}
}
class foo
{
~foo()
{
}
}
Objects referenced by static fields are not simply finalized unless you clear (set to null) the field - and even then it is non-deterministic and not guaranteed. Static fields count as root objects.
When (and why) would you expect this to be collected/finalized? It is still accessible...
Objects referenced by static fields are always reachable (assuming no class unloading or any other GC funkiness) and will never be collected.
Even though you might expect the finalizer on static objects to run when the process is shutdown, there are no guarantees there either:
http://blogs.msdn.com/cbrumme/archive/2004/02/20/77460.aspx (look at the section titled "V1 & V1.1 Finalization Guarantees"). I'm not sure how much of this has changed in .NET 2.0 or later.
That's not a destructor. It's a finalizer. That's a different thing. As the other two have said, because this is a static, it will never be collected, hence the finalizer will never run.
Related
The FxCop warning "Classes with disposable fields should be disposable" sometimes confuses me. See contrived example below
Only one type creates and owns the disposable resource, but any number of types can use (or "borrow") this resource. I have seen developes take the FxCop warning on Util1 and Util2 to indicate that since they have a field of a disposable type, they must implement Dispose and dispose that field. That's clearly not what you want here.
Is the problem that
Making classes that only borrow disposable resources is an antipattern. The disposable resource could be passed as a method argument to Util1 and Util2, and the problem would go away. Only classes that create disposable resource should ever have them as fields, so that the field itself is what indicates ownership.
The warning isn't clever enough. It should be warning when types that own disposable resources aren't themselves disposable, and in this scenario only one class owns it, while the others borrow it. The fact that it is injected only from a constructor parameter could have been used by a more clever rule to detect that the warning should not be raised for the borrowing class.
Something else?
static class Program
{
public static void Main()
{
using(var r = new SomeResource())
{
Console.WriteLine(new Util1(r).Foo());
Console.WriteLine(new Util2(r).Foo());
}
}
}
public sealed class SomeResource : IDisposable
{
private readonly NativeResource native;
public void SomeResource()
{
native = Native.CreateDisposableThing();
}
public void Dispose()
{
native.Dispose();
}
}
public sealed class Util1 {
private readonly SomeResource res;
public Util1(SomeResource res) { this.res = res; }
public string Foo() { /* uses res */ }
}
public sealed class Util2 {
private readonly SomeResource res;
public Util2(SomeResource res) { this.res = res; }
public string Foo() { /* uses res */ }
}
In most of case if you have a disposable field, it means you want to use it later and wrap it. If you return this field to external code, it can be disposed and break your own class unless you are able to check if resource was disposed before each usage.
If you just want to make a fabric, you don't need to keep the disposble resource as field.
That's why this rules is often true but in some special rare case you are able to make a "won't fix".
Other patterns are pretty rare because it is hard to maintain without introducing bug.
Using C#.
I have a MainFoo class:
class MainFoo
{
private Foo foo;
public MainFoo()
{
this.foo = new Foo();
}
public CreateNewFoo()
{
this.foo = new Foo();
}
public DoCurrentFoo()
{
this.foo.Do();
}
}
A Foo class:
class Foo
{
~Foo()
{
this.DoEnd();
}
public void Do() {}
private void DoEnd() {}
}
I want to be able to call the method DoEnd() in Foo class whenever private Foo; get's initialized again. This method DoEnd() is private and I would like to keep it that way (so not accessible from MainFoo).
Since the same Foo get's initialized again, I though the instance would loose it's reference so it would call destructor. But this gets only called when MainFoo instance lost reference.
Question: How to dispose object instance when it lost it's reference?
Destructors are not guaranteed to be called at any specific time, or even get called at all. Typically, you should not rely on destructor and should implement IDisposable and call Dispose yourself.
Most conviniently, this can be done with using(...){ }.
Getting back to your sample, you can also dispose object on assignment of property (as Jason Watkins suggested), but make sure that it is not used anywhere else.
public Foo F
{
get{return foo;}
set
{
if( foo != null)
foo.Dispose();
foo = value;
}
}
You cannot, it's the Garbage Collector's job.
From MSDN:
In C#, garbage collection is handled by the common language runtime (CLR) with similar functionality to that of the JVM. The CLR garbage collector periodically checks the memory heap for any unreferenced objects, and releases the resources held by these objects.
I have a class with extensive static members, some of which keep references to managed and unmanaged objects.
For instance, the static constructor is called as soon as the Type is referenced, which causes my class to spin up a blockingQueue of Tasks. This happens when one of the static methods is called, for example.
I implemented IDisposable, which gives me methods to handle disposal on any instance objects I created. However, these methods are never called if the consumer doesn't create any instance objects from my class.
How and where do I put code to dispose of references maintained by the static portion of my class? I always thought that disposal of static-referenced resources happened when the last instance object was released; this is the first time I've ever created a class where no instances may ever be created.
The static variable of your class are not garbage collected until the app domain hosting your class is unloaded. The Dispose() method will not be called, because it is an instance method, and you said that you wouldn't create any instances of your class.
If you would like to make use of the Dispose() method, make your object a singleton, create one instance of it, and dispose of it explicitly when your application is about to exit.
public class MyClass : IDisposable {
public IList List1 {get; private set;}
public IDictionary<string,string> Dict1 {get; private set;}
public void Dispose() {
// Do something here
}
public static MyClass Instance {get; private set;}
static MyClass() {
Instance = new MyClass();
}
public static void DisposeInstance() {
if (Instance != null) {
Instance.Dispose();
Instance = null;
}
}
}
public class Logger : IDisposable
{
private string _logDirectory = null;
private static Logger _instance = null;
private Logger() : this(ConfigurationManager.AppSettings["LogDirectory"])
{
AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;
}
private Logger(string logDirectory)
{
}
public static Logger Instance
{
get
{
if (_instance == null)
_instance = new Logger();
return _instance;
}
}
private void CurrentDomain_ProcessExit(object sender, EventArgs e)
{
Dispose();
}
public void Dispose()
{
// Dispose unmanaged resources
}
}
You should dispose this objects manually, there is no way to create a "finalizer" for static resources.
If you really want to have static members which keep references to unmanaged objects
just create a method for disposing the unmanaged objects and "force" consumer to use it on exit.
By "force" I mean document your class with a paragraph that states "when" and "why" to use this "dispose" method.
Do it either if you are the sole consumer (or your code...) or you plan to distribute your class.
Also try to use a somehow descriptive name (to that "dispose" method) such as "DisposeStatics", "AlwaysDispose", "DisposeAtEnd" etc.
How does C#, or other languages for that matter, handle memory allocation (and memory de-allocation) between these two scenarios:
1.) A method on a static class is invoked.
public Program {
Foo foo = Loader.load();
}
public static Loader {
public static Foo load() {
return new Foo();
}
}
2.) A method is invoked on an instance, which then falls out of scope.
public Program {
Foo foo = new Loader().load();
}
public Loader {
public Foo load() {
return new Foo();
}
}
I suppose the static class is loaded, and remains, in memory; whereas the class instance succumbs to garbage collection at C#'s leisure. Are there any pros or cons to these two paradigms? Is there ever a time when you have a class that never needs to be instantiated (i.e. some sort of resource loader or factory), but you use the second methodology anyway to take advantage of garbage collection?
The important part of my question is whether or not the first paradigm, while being conceptually correct in some circumstances, may suffer from holding on to memory unnecessarily.
Your second example doesn't work, so let's explore the real options:
1.) A method on a static class is invoked.
public Program {
Foo foo = Loader.Load();
}
public static Loader {
public static Foo Load() {
return new Foo();
}
}
2.) A static method in a non-static class is invoked.
public Program {
Foo foo = Loader.Load();
}
public Loader {
public static Foo Load() {
return new Foo();
}
}
3.) An instance method is invoked on an instance
public Program {
Foo foo = new Loader().Load();
}
public Loader {
public Foo Load() {
return new Foo();
}
}
The two first are the same. Calling a static method is the same regardless if the class is static or not.
The third option will create an instance of the class on the heap. As the class has no data members, it will only be something like 16 bytes. It will be garbage collected eventually, but due to the small size it doesn't matter much when that happens.
Calling an instance method is also slightly different from a static method. A reference to the class instance is sent along, that you can access through the this keyword. It makes little difference in this case as there is no real data in the object to access.
The second form creates a temporary Loader object (which is very cheap). You will always have to load the Loader class, no matter which approach you choose.
There is very little performance (memory saving) to gain here. You would normally choose for a static member in a static class if there is no 'state' needed outside the methods local vars.
A static method, field, property, or event is callable on a class even when no instance of the class has been created.
http://msdn.microsoft.com/en-us/library/79b3xss3(VS.80).aspx
So in that sense your static methods behaves just as it would if you used it from within a class instance: it is scoped to the type.
I cannot find any sources for this, but from my knowledge of programming, when you refernce a class(non static), it's structure is loaded into memory
Creating an instance of a class just to call a method, would waste a lot of processing power(due to creating an instance, assigning it memory, and the garbage collecting).
Instead of keeping the definition, and then on top of it, an instance. Why not just keep the definition(static).
As long as you don't store any data in static variables, your static method should take up the same amount of memory as your non static method definition. But using a static method, only the method will be kept in memory and be ready to be called whenever you need without creating instances. Where as, if the method is non static, it will need to be instantiated(using up memory and processing power) and the garbage collected(freeing memory and using up cpu) therefore it is definitely better using a static member. Thats what they are there for.
I am using .net 1.1. I have a session class in which I have stored many static variables that hold some data to be used by many classes.
I want to find a simple way of destroying this class instead of resetting every variable one by one. For example if there is a static class MyStatic, I would have liked to destroy/remove this class from the memory by writing MyStatic = null, which is not currently possible,
Additional question.
The idea of singleton is good, but I have the following questions:
If singleton is implemented, the 'single' object will still remain in the memory. In singleton, we are only checking if an instance is already existing. how can i make sure that this instance variable also gets destroyed.
I have a main class which initializes the variable in the static class. Even if I plan to implement a Rest() method, I need to call it from a method, for eg, the destructor in the main class. But this destructor gets called only when GC collects this main class object in the memory, which means the Reset() gets called very late
thanks
pradeep
Don't use a static class to store your variables. Use an instance (and make it a singleton if you only want one instance at any given time.) You can then implement IDisposible, and just call Dispose() when you want to destroy it.
For more information check out this site: http://csharpindepth.com/Articles/General/Singleton.aspx
EDIT
The object is still subject to garbage collection, so unless you are using lots of unmanaged resources, you should be fine. You can implement IDisposible to clean up any resources that need to be cleaned up as well.
Instead of a static class, have a static instance of a class:
class Foo
{
public int Something;
public static Foo Instance = new Foo();
public void Reset()
{
Instance = new Foo();
}
}
void test
{
int i = Foo.Instance.Something;
}
You can also delegate to an instance of the class:
class Foo
{
public int Something
{
get { return instance.something; }
}
private int something;
private static Foo instance = new Foo();
public void Reset()
{
instance = new Foo();
}
}
void test
{
int i = Foo.Something;
}
There's no way to destroy a static unless it resides in a separate AppDomain in which case you can get rid of it by unloading the AppDomain. However it is usually better to avoid statics.
EDIT: Additional question
When the singleton is no longer referenced it will be collected just as everything else. In other words, if you want it collected you must make sure that there are no references to it. It goes without saying that if you store a static reference to your singleton, you will have the same problem as before.
Use a Singleton like ktrauberman said, and have an initialization method or a reset method. You only have to write the code once and call the method.
You destroy objects, not classes. There's nothing wrong with static classes--C# provides them for a reason. Singletons are just extra overhead, unless you actually need an object, e.g. when you have to pass the object as a parameter.
Static classes contain only static variables. These variables tend to last for the lifetime of the app, in which case you don't have to worry about disposing referenced objects, unless you have a mild case of OCD. That just leaves the case where your static class allocates and releases resources throughout its lifetime. Dispose of these objects in due course as you usually would (e.g., "using...").
The best way in your condition is to have an Reset() method built-in as well, which can reset the values of the class.
class myclass
{
private static myclass singleobj = null;
private myclass(){}
public static myclass CreateInstance()
{
if(singleobj == null)
singleobj = new myclass();
return singleobj
}
}
Building on Ahemd Said's answer: (and props to him!)
class Singleton
{
private static Singleton instance = null;
private Singleton(){} // private constructor: stops others from using
public static Singleton Instance
{
get { return instance ?? (instance = new Singleton()); }
set {
if (null != value)
{ throw new InvalidValueException(); }
else
{ instance = null; }
}
}
}
void SampleUsage()
{
Singleton myObj = Singleton.Instance;
// use myObj for your work...
myObj.Instance = null; // The set-operator makes it ready for GC
}
(untested... but mostly right, I think)
You could also add in usage of the IDispose interface for more cleanup.
You can create a method in the static class which resets the values of all properties.
Consider you have a static class
public static class ClassA
{
public static int id=0;
public static string name="";
public static void ResetValues()
{
// Here you want to reset to the old initialized value
id=0;
name="";
}
}
Now you can use any of the below approaches from any other class to reset value of a static class
Approach 1 - Calling directly
ClassA.ResetValues();
Approach 2 - Invoking method dynamically from a known namespace and known class
Type t1 = Type.GetType("Namespace1.ClassA");
MethodInfo methodInfo1 = t1.GetMethod("ResetValues");
if (methodInfo1 != null)
{
object result = null;
result = methodInfo1.Invoke(null, null);
}
Approach 3 - Invoking method dynamically from an assembly/set of assemblies
foreach (var Ass in AppDomain.CurrentDomain.GetAssemblies())
{
// Use the above "If" condition if you want to filter from only one Dll
if (Ass.ManifestModule.FullyQualifiedName.EndsWith("YourDll.dll"))
{
List<Type> lstClasses = Ass.GetTypes().Where(t => t.IsClass && t.IsSealed && t.IsAbstract).ToList();
foreach (Type type in lstClasses)
{
MethodInfo methodInfo = type.GetMethod("ResetValues");
if (methodInfo != null)
{
object result = null;
result = methodInfo.Invoke(null, null);
}
}
break;
}
}
Inject the objects into the static class at startup from a non static class that implements IDisposable, then when your non static class is destroyed so are the objects the static class uses.
Make sure to implement something like "Disable()" so the static class is made aware it's objects have just been set to null.
Eg I have a logger class as follows:
public static class Logger
{
private static Action<string, Exception, bool> _logError;
public static void InitLogger(Action<string, Exception, bool> logError)
{
if(logError != null) _logError = logError;
}
public static void LogError(string msg, Exception e = null, bool sendEmailReport = false)
{
_logError?.Invoke(msg, e, sendEmailReport);
}
In my constructor of my Form I call the following to setup the logger.
Logger.InitLogger(LogError);
Then from any class in my project I can do the following:
Logger.LogError("error",new Exception("error), true);