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

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.

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.

Problems with managing shared ownership of IDisposable objects

[There is a similar question Shared ownership of IDisposable objects in C# but the accepted answer suffers from similar design problems which my solution has]
I have been trying to think around this problem having seen many designs taking a blind leap of faith in garbage collector when working in c#. Reason being many times its easy to ignore that one need to handle the IDisposable rather carefully making them close equivalent of resource allocation in c++. I understand that pedantically speaking Dispose is not the equivalent of c++ destructor but if you are holding on to native resources which needs to be cleaned in a deterministic manner it becomes very similar.
But if the object is shared by multiple resources (for eg. an HttpClient object which is meant to be created and used concurrently for performance), who owns the responsibility of calling Dispose since there is no single owner? To solve this problem I came up with a SharedOwner library which has a similar interface as shared_ptr.
Code snippet:
SharedOwner:
public static SharedHandle<T> MakeSharedHandle(Func<T> createSharedOwner)
{
var obj = new SharedHandle<T>(createSharedOwner());
return obj;
}
public SharedHandle(T obj)
{
AddReference();
m_object = obj;
}
public Handle<T> GetHandle()
{
AddReference();
return new Handle<T>(this);
}
internal void Decrement()
{
if (Interlocked.Decrement(ref m_refCounter) == 0)
{
m_object.Dispose();
m_object = default(T);
}
}
internal T GetInternalHandler() { return m_object; }
private void AddReference()
{
Interlocked.Increment(ref m_refCounter);
}
~SharedHandle()
{
m_object.Dispose();
}
Handle
is a transparent wrapper that manages the ref counting calls keeping that abstracted from consumers.
public sealed class Handle<T> : IDisposable where T : IDisposable
{
private SharedHandle<T> m_handle;
bool disposed = false;
internal Handle(SharedHandle<T> handle) { m_handle = handle; }
public void Dispose()
{
if (!disposed)
{
m_handle.Decrement();
GC.SuppressFinalize(this);
disposed = true;
}
}
~Handle()
{
if (!disposed)
{
m_handle.Decrement();
}
}
The typical usage pattern that I imagined would be:
using (var sharedClient = this.m_sharedClient.GetHandle()) // m_sharedClient is the SharedHandle passed
{
var httpClient = (HttpClient)sharedClient;
// use httpClient
}
Now I see two issues with this approach which deviate it from the original motivation of simulating shared_ptr behavior:
The first reference is held by SharedHandle itself. So even when all Handles are out of scope one reference would still be held by SharedHandle thereby making the if block in Decrement unreachable.
The final Dispose happens when the SharedHandle dies which in lot of sense is no better than not calling Dispose on the underlying object itself. Hence making the solution much less valuable.
I am thinking of moving the reference counting to Handle and using SharedHandle as the control block in shared_ptr but then that means that one may end up with a valid SharedHandle object holding on to a Disposed internal object.
Another alternative that I can think of is making SharedHandle derive from IDisposable and just call Decrement in Dispose. But then this brings other set of design issues. Is there anything that can be done to solve this problem in a more elegant way?

How to stop an object (and everything inside it) from being finalized?

In my two-week long quest to solve a problem:
How to get notified before static variables are finalized
Unload event for the default Application Domain?
Profiling ASP.net applications over the long term?
the fundamental problem is the garbage collector. My object's Finalizer would have been the ideal time to react when the object is about to be freed (i.e. to have its resources reclaimed). The problem with the .NET garbage collection system is that by the time my finalizer is called, it's entirely likely that other objects i own have already been finalized.
The problem would be trivial to solve if i were interoping with native class objects. The garbage collector is unable to free those objects behind my back (and without my permission). So by the time my managed object's finalizer is called, i know that my internal state is still valid.
What i need is a way to tell the garbage collector to keep your hands off.
Is there a ways to prevent an object from being finalized?
For example
For example, the following code is buggy, because the finalizer mistakenly things that the private _values object still exists. In reality it is likely already finalized out from under me:
class Sqm
{
private List<Value> _values = new List<Value>();
//finalizer
public ~Sqm()
{
Shutdown();
}
protected void Shutdown()
{
foreach (var value in _values) //<-- crash; _values no longer exists
SaveValueToHardDrive(value); //<-- crash; value no longer exists
}
}
What i need is a way to tell the garbage collector not to finalize that list object, or any of the objects inside it:
class Sqm
{
private List<Value> _values = new List<Value>();
//constructor
public Sqm()
{
GC.LetMeManuallyFinalize(_values);
}
//finalizer
public ~Sqm()
{
Shutdown();
GC.ManuallyFinalize(_values);
}
protected void Shutdown()
{
foreach (var value in _values)
SaveValueToHardDrive(value);
}
}
That has two possible problems:
there is no GC.ManuallyFinalize method
it might suppress freeing the _values list itself, but the objects it references would likely still be finalized behind my back:
protected void Shutdown()
{
foreach (var value in _values)
SaveValueToHardDrive(value); //<---crash, contained object already finalized
}
So now i need to ensure that the objects, as they are added to the list, are also excluded from finalization:
public void AddSample(String name, Int64 value)
{
Entry entry = GetEntryByName(name);
if (entry == null)
{
entry = new Entry();
GC.LetMeManuallyFinalize(entry);
}
entry.Count += 1;
entry.Sum += value;
entry.Average = entry.Sum / entry.Count;
}
//finalizer
public ~Sqm()
{
foreach (var value in _values)
GC.ManuallyFinalize(value);
GC.ManuallyFinalize(_values);
}
That probably has the problem that while Entry has no other internal objects, i don't know about List<T>. And the garbage collector might perform an unwanted labotomy on _values even though _values itself hasn't been finalized.
Use GCAlloc.Alloc()
#MatthewWatson had an excellent idea. i think it would be useful to point out why it's wrong. Use GCAlloc.Alloc to hold a reference to the object. Then you use can access it during your finalizer:
public Sqm()
{
private List<Value> _values = new List<Value>();
private GCHandle _valuesHandle; //handle to keep _values alive
//constructor
Sqm()
{
//prevent _values from being finalized
_valuesHandle = GCAlloc.Alloc(_values);
}
//finalizer
~Sqm()
{
try
{
Shutdown(_values); //Safe, right? RIGHT? _values couldn't have been finalized
}
finally
{
_valuesHandle.Free();
}
}
private void Shutdown(List<Values> values)
{
foreach (var value in values)
{
//The list itself might not have been finalized
//But objects used internally to Microsoft's List<T> class have been finalized
//and objects in the list itself were already finalized
SaveValueToHardDrive(value); //<--BAD: values inside list were already finalized
}
}
}
Note: It also probably fails because of the pseudo-documented behavior. From The Truth About GCHandles:
When you create a new GCHandle, a new entry in the AppDomain's handle table is created. This entry is kept until the handle is freed (via GCHandle.Free()) or the AppDomain is unloaded.
Emphasis mine.
So that's right out. i need to tell the garbage collector
Do not finalize this object (and everything inside it)
The tricky part is the internal private members of classes i do not own; even an object still referenced by GCAlloc will still have objects it depends on finalized behind it's back.
Sample Usage
public static Foo
{
public static Sqm = new Sqm();
}
Foo.Sqm.AddSample("QueryCustomerInfo", stopwatch.TotalMicroseconds);
It's a very bad practice to do any long term operations during finalization, like input-output, anyway.
You should consider storing your _values lists of your objects in the static list - this will prevent values from destruction. When your object is being finalizing, you could save the reference to the inner list in another static list, which is checked periodically. When it contains references to lists, it will mean that your object was destructed and values it contained should be saved.
class Sqm
{
private static List<List<Value>> = _lists = new List<List<Value>>();
private static List<List<Value>> = _finalizationQueue = new List<List<Value>>();
private List<Value> _values = new List<Value>();
Sqm() { _lists.Add(_values); }
~Sqm() { _finalizationQueue.Add(_values); }
public static void CheckAndSave()
{
foreach(var list in _finalizationQueue)
SaveValues(list);
}
}
UPD.: If domain may be shutdown when you dont want it to, your only way is to store values in another domain.

Deallocation of resources when using static members

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.

Singleton factory, sort of

Sorry if this has been answered elsewhere... I have found a lot of posts on similar things but not the same.
I want to ensure that only one instance of an object exists at a time BUT I don't want that object to be retained past its natural life-cycle, as it might be with the Singleton pattern.
I am writing some code where processing of a list gets triggered (by external code that I have no control over) every minute. Currently I just create a new 'processing' object each time and it gets destroyed when it goes out of scope, as per normal. However, there might be occasions when the processing takes longer than a minute, and so the next trigger will create a second instance of the processing class in a new thread.
Now, I want to have a mechanism whereby only one instance can be around at a time... say, some sort of factory whereby it'll only allow one object at a time. A second call to the factory will return null, instead of a new object, say.
So far my (crappy) solution is to have a Factory type object as a nested class of the processor class:
class XmlJobListProcessor
{
private static volatile bool instanceExists = false;
public static class SingletonFactory
{
private static object lockObj = new object();
public static XmlJobListProcessor CreateListProcessor()
{
if (!instanceExists)
{
lock (lockObj)
{
if (!instanceExists)
{
instanceExists = true;
return new XmlJobListProcessor();
}
return null;
}
}
return null;
}
}
private XmlJobListProcessor() { }
....
}
I was thinking of writing an explicit destructor for the XmlJobListProcessor class that reset the 'instanceExists' field to false.
I Realise this is a seriously terrible design. The factory should be a class in its own right... it's only nested so that both it and the instance destructors can access the volatile boolean...
Anyone have any better ways to do this? Cheers
I know .NET 4 is not as widely used, but eventually it will be and you'll have:
private static readonly Lazy<XmlJobListProcessor> _instance =
new Lazy<XmlJobListProcessor>(() => new XmlJobListProcessor());
Then you have access to it via _instance.Value, which is initialized the first time it's requested.
Your original example uses double-check locking, which should be avoided at all costs.
See msdn Singleton implementation on how to do initialize the Singleton properly.
just make one and keep it around, don't destroy and create it every minute
"minimize the moving parts"
I would instance the class and keep it around. Certainly I wouldn't use a destructor (if you mean ~myInstance() )...that increases GC time. In addition, if a process takes longer than a minute, what do you do with the data that was suppose to be processed if you just return a null value?
Keep the instance alive, and possibly build a buffer mechanism to continue taking input while the processor class is busy. You can check to see:
if ( isBusy == true )
{
// add data to bottom of buffer
}
else
{
// call processing
}
I take everyone's point about not re-instantiating the processor object and BillW's point about a queue, so here is my bastardized mashup solution:
public static class PRManager
{
private static XmlJobListProcessor instance = new XmlJobListProcessor();
private static object lockobj = new object();
public static void ProcessList(SPList list)
{
bool acquired = Monitor.TryEnter(lockobj);
try
{
if (acquired)
{
instance.ProcessList(list);
}
}
catch (ArgumentNullException)
{
}
finally
{
Monitor.Exit(lockobj);
}
}
}
The processor is retained long-term as a static member (here, long term object retention is not a problem since it has no state variables etc.) If a lock has been acquired on lockObj, the request just isn't processed and the calling thread will go on with its business.
Cheers for the feedback guys. Stackoverflow will ensure my internship! ;D

Categories

Resources