Deallocation of resources when using static members - c#

Consider situation when we have a class with couple of static methods that use one static object.
public class Person
{
private static PresonActions actions = new PresonActions();
public static void Walk()
{
actions.Walk();
}
}
I know that the life cycle of static members in asp.net apps is equals to appdomain life cycle.
So this means that the object is not destroyed and the resources are not deallocated until I'll restart the appdomain.
But if we will use a property to create an instance of class PresonActions each time something access it, will the object will be destroyed or not?
public class Person
{
private static PresonActions actions { get { return new PresonActions(); } }
public static void Walk()
{
actions.Walk();
}
}
thanks.

Static variable continuouse allocation is an Evil. Keep an eye on your memory consuption, especially if you are talking about server side component (ASP.NET).
To answer your question: GC collects when he can an object which none longer reference by anyone in application.
Do not do this. It's very easy jump into memory problems with this approach and after spend hours to profile and find memory leaks.
If you want to change an object content, write a function that updates object content, without creating a new instance of it.

In your second code example, the garbage collector will destroy the object some time after the call to actions.Walk(). The garbage collector does this in a non-deterministic fashion, i.e. you cannot determine when it will perform this operation.
If your type is using resources which you want to dispose of deterministically, then the type should implement IDisposable and it's implementation of the Dispose method should perform the disposal of those resources.
Consuming code can then either call this method directly or use a using block to dispose of the object which in turn disposes of it's resources.
e.g.:-
public class PresonActions : IDisposable
{
...
public void Dispose()
{
...
}
}
public class Person
{
public static void Walk()
{
using(var actions = new PresonActions())
{
actions.Walk();
}
}
}
Note that, since you are not using the instance for more than one method call, there is no point creating it in a static property. It can be created it within the method, which allows use of a using block.

Related

Unclear behavior by Garbage Collector while collecting instance properties or fields of reachable object

Till today I was thinking that members of reachable objects are also considered to be reachable.
But, today I found one behavior which creates a problem for us either when Optimize Code is checked or application is executed in Release Mode. It is clear that, release mode comes down to the code optimization as well. So, it seems code optimization is reason for this behavior.
Let's take a look to that code:
public class Demo
{
public Action myDelWithMethod = null;
public Demo()
{
myDelWithMethod = new Action(Method);
// ... Pass it to unmanaged library, which will save that delegate and execute during some lifetime
// Check whether object is alive or not after GC
var reference = new WeakReference(myDelWithMethod, false);
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true);
GC.WaitForPendingFinalizers();
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true);
Console.WriteLine(reference.IsAlive);
// end - Check whether object is alive or not after GC
}
private void Method() { }
}
I simplified code a bit. Actually, we are using our special delegate, not Action. But the behavior is same. This code is written in mind with "members of reachable objects are also considered to be reachable". But, that delegate will be collected by GC asap. And we have to pass it to some unmanaged library, which will use it for some time.
You can test demo by just adding that line to the Main method:
var p = new Demo();
I can understand the reason of that optimization, but what is the recommended way to prevent such case without creating another function which will use that variable myDelWithMethod which will be called from some place? One, option I found that, it will work if I will set myDelWithMethod in the constructor like so:
myDelWithMethod = () => { };
Then, it won't be collected until owning instance is collected. It seems it can't optimize code in the same way, if lambda expression is setted as a value.
So, will be happy to hear your thoughts. Here are my questions:
Is it right that, members of reachable objects are also considered to
be reachable?
Why it is not collected in case of lambda expression?
Any recommended ways to prevent collection in such cases?
However strange this would sound, JIT is able to treat an object as unreachable even if the object's instance method is being executed - including constructors.
An example would be the following code:
static void Main(string[] args)
{
SomeClass sc = new SomeClass() { Field = new Random().Next() };
sc.DoSomethingElse();
}
class SomeClass
{
public int Field;
public void DoSomethingElse()
{
Console.WriteLine(this.Field.ToString());
// LINE 2: further code, possibly triggering GC
Console.WriteLine("Am I dead?");
}
~SomeClass()
{
Console.WriteLine("Killing...");
}
}
that may print:
615323
Killing...
Am I dead?
This is because of inlining and Eager Root Collection technique - DoSomethingElse method do not use any SomeClass fields, so SomeClass instance is no longer needed after LINE 2.
This happens to code in your constructor. After // ... Pass it to unmanaged library line your Demo instance becomes unreachable, thus its field myDelWithMethod. This answers the first question.
The case of empty lamba expression is different because in such case this lambda is cached in a static field, always reachable:
public class Demo
{
[Serializable]
[CompilerGenerated]
private sealed class <>c
{
public static readonly <>c <>9 = new <>c();
public static Action <>9__1_0;
internal void <.ctor>b__1_0()
{
}
}
public Action myDelWithMethod;
public Demo()
{
myDelWithMethod = (<>c.<>9__1_0 ?? (<>c.<>9__1_0 = new Action(<>c.<>9.<.ctor>b__1_0)));
}
}
Regarding recommended ways in such scenarios, you need to make sure Demo has lifetime long enough to cover all unmanaged code execution. This really depends on your code architecture. You may make Demo static, or use it in a controlled scope related to the unmanaged code scope. It really depends.

What happens if an object is "rereferenced" in it's finalizer?

Appearently, in java; "the object will not be collected until it gets unreachable again" (What if a finalizer makes an object reachable?). I assume the same holds in C#, but does it?
A quick example:
public static void MyWeakCache
{
private static readonly ICollection<WeakReference<MyFinalizableObject>> cache;
private static readonly IList<MyFinalizableObject> pendingRemoval;
// Other implementation
public static void Register(MyFinalizableObject myObj)
{
cache.Add(new WeakReference<MyFinalizableObject>(myObj));
}
public static void Deregister(MyFinalizableObject myObj)
{
pendingRemoval.Add(myObj);
}
}
public class MyFinalizableObject
{
public MyFinalizableObject()
{
MyWeakCache.Register(this);
}
~MyFinalizableObject()
{
// Object is reachable again after this call.
MyWeakCache.Deregister(this);
}
}
If the finalizer creates a new reference to the object then the object is not garbage collected. But there's no way of knowing when the finalizer will run or if it will run.
That creates a scenario where, for an unknowable period of time between when the last reference to the object is removed and when the finalizer is called, the object is in limbo, sitting in memory with no references to it. The natural flow of garbage collection is that no object should return from this state. It's like bringing Frankenstein to life. He's dead, let nature take its course.
It's interesting but has no practical application because there's no reason to do this. By definition finalizers don't exist to maintain references to objects. The only thing it can accomplish is creating unpredictable behaviors and bugs.

Is it good practice to lock on a threaded instance of an object being used throughout an application?

Every example I've ever seen of locking uses a private object to lock specific blocks of code, and Thread Synchronization (C#) gives the same kind of example, but also says "Strictly speaking, the object provided is used solely to uniquely identify the resource being shared among multiple threads, so it can be an arbitrary class instance. In practice, however, this object usually represents the resource for which thread synchronization is necessary." (Emphasis mine.) In my example here, and in my code, there is only one instance of "MyClass", which is running on its own thread, and a reference to it is passed around to various other classes.
Is it OK to lock on the MyClass reference and then call Ready(), or should I instead put a private object() within MyClass and lock on that, as shown in the LockedReady() method? Thank you for your answer, in advance.
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var uc = new UserClass();
uc.DoThings();
}
}
public class MyClass
{
public bool Ready()
{
//determine if the class is ready to perform its function
//assumes that the instance of MyClass is locked,
//as shown in UserClass.DoThings
}
private object _readyLock = new object();
public bool LockedReady()
{
lock (_readyLock)
{
//determine if the class is ready to perform its function
//no assumption made that the object is locked, as
//shown in AnotherClass.DoAnotherThing()
}
}
}
public class UserClass
{
private MyClass _myc;
public UserClass()
{
var t = new Thread(SetupMyClass);
t.Start();
}
private void SetupMyClass()
{
_myc = new MyClass();
}
public void DoThings()
{
lock(_myc)
{
if (_myc.Ready())
{
//Do things
}
}
}
public void DoOtherThings()
{
var ac = new AnotherClass(_myc);
ac.DoAnotherThing();
}
}
public class AnotherClass
{
private MyClass _myc;
public AnotherClass(MyClass myClass)
{
_myc = myClass;
}
public void DoAnotherThing()
{
if (_myc.LockedReady())
{
//do another thing
}
}
}
}
Functionally, it doesn't matter, one object doesn't perform better than the other, unless there is shared use of that object by other locking concerns.
With C#, it isn't uncommon to lock on the actual domain object, rather than a surrogate object for the lock. It is also common to see a member object used, and a common legacy example is the SyncRoot object on the early System.Collections. Either way works, as long as you use a reference type.
However, the argument to be made for using an internal surrogate lock object is one of encapsulation. It eliminates the possibility of external interference if a user of your class decides to use your class as a lock. Using an internal lock object protects your locks from external interference, so one could argue that locking is an implementation detail that should be hidden.
The important thing is to ensure it is correct and appropriate. Make sure your locking is done at an appropriate granularity. (For example, using a static lock object probably isn't the best approach for a non-singleton, and probably not even most singletons). In cases where your class has multiple mutually exclusive threaded operations, you don't want to lock on "this" or you have unnecessary contention. That is like having one red light for 2 non-overlapping intersections.

Disposing an IDisposable object stored in a public static field

If a class has an instance field that implements IDisposable then the containing class implements IDisposable and class that fields Dispose method from within its Dispose method.
public class A : IDisposable
{
public System.Drawing.Font font = new Font("Arial", 10.0f);
public void Dispose()
{
font.Dispose()
}
}
(I know I didn't do the dispose pattern correctly, but for sample code should be good enough)
If the field is a static field though where should the call to the field's Dispose be?
public class B
{
public static System.Drawing.Font font = new Font("Arial", 10.0f);
}
I could make class B implement IDisposable and have that call font.Dispose but if B.font is used again later on that would cause problems. As well as you'd have to remember that dispise accessing a static method you need to create an instance just to call Dispose.
I could also make a static Dispose method but then users have to remember to call Dispose and have to make sure they're the last user of it in the program.
Static fields are initialised when the type is loaded.
Therefore it logically it makes sense to dispose the object assigned to the static field when the containing type is unloaded.
However, types are not unloaded. There may be some exotic complication here around AppDomains, but I suspect that doesn't apply in your case.
Therefore I wouldn't dispose the instance, otherwise you will have a publicly available instance of an object that is unfit for use.
If the field is static, then maybe the intention is to have it last for the complete duration of the application? Because then it will only need to be disposed of when the application shuts down. And that will happen one way or the other, by itself-
If you plan to reassign the static field to different IDisposable objects several times during the lifetime of the application, then of course you would want to dispose the old object when you reassign. Maybe you could use a property for that? Not that I have thought a lot about it, but something like:
// private - don't write to this field from outside the property setter
static Font font = new Font("Arial", 10.0f));
public static Font Font
{
get
{
return font;
}
set
{
var oldFont = font;
if (oldFont != null)
oldFont.Dispose();
font = value;
}
}
You dispose of it like any other object. It doesn't make a difference. A static object is just an object that is available per class. It's still an instance of something. Granted, you probably wouldn't want to do this since after you dispose of it someone can still access it and get a ObjectDisposedException exception.
static void Main(string[] args)
{
using (Test.Instance)
{
}
Thread.Sleep(TimeSpan.FromSeconds(10));
}
public class Test:IDisposable
{
public static Test Instance = new Test();
public void Dispose()
{
Console.WriteLine("Disposed");
}
}
And the output is:
Disposed
Per your updated example:
public class A
{
public static System.Drawing.Font font = new Font("Arial", 10.0f));
}
You can just do A.font.Dispose() or using(A.font)
In general I think the idea is you really wouldn't have a public static disposable field since by making it static you imply it should be around for the lifetime of the application. If it has to be disposable you should could make it lazy and make it be thread-safely re-initializable, otherwise accessing it after disposing will throw exceptions. Or you can have a hook into your application end code and safely dispose of all static disposables there. You can register your disposable on start somewhere as well. Just an idea
You can't dispose a static class because there is no instance of it

Should an ObjectContext in a static method be disposed?

Just a quick sanity check here!
If I have a static method in an instance class e.g:
public class myClass
{
public static void AMethod()
{
//do somit
}
}
Would it cause problems if I was making reference to IDisposable resources in the method body, an object context for example?
public static void AMethod()
{
ObjectContext context = new ObjectContext();
// do somit
}
By would it cause problems, I mean, would it retain the object context behind the scenes after the end of the method body due to the fact it was a static method?
The class as can be seen, isn't static, and the variable is local to the method.
I'm aware that I should be using 'using' here, just curious as to whether this particular combo of events could/would cause memory leaks.
In order to avoid any problems it is recommended to dispose IDisposable resources as soon as you have finished using them. This could happen by wrapping them in a using statement:
public static void AMethod()
{
using (ObjectContext context = new ObjectContext())
{
// do something
}
}
After leaving the scope of your method AMethod, your context object can't be used anymore so it'll be garbage collected eventually.
But as it implements IDisposable, you should use the using statement:
using (ObjectContext context = new ...)
{
// Use the context here
}

Categories

Resources