The objects of type FileStream or DB handles have to be properly closed as it use Windows handles internally. Likewise, Threads also use Windows handles right? Does thread has some internal mechanisms to release those Windows handles?
Thread does not implement IDisposable so it can't be disposed unlike Stream or DB related objects.
Runtime takes care of necessary cleanup of related native object when thread's code finishes execution and GC will normally take care of managed Thread object similarly to other finalizable objects.
Note that there is no direct consistent relationship between OS and managed threads Getting the thread ID from a thread.
Related
I wrote a C # code to run an unmanged thread along with others managed threads in Mono. The unmanaged thread is real time because it is created with Xenomai libraries with the use of a wrapper. The unmanaged thread executes a function written in C# (managed code). I saw that the thread is blocked by the GC because of the priority inversion (I supposed) so I tried to use only fixed fields. However, the final result is not chaged.
Naturally I am working on linux and I am using Mono JIT compiler version 3.2.6
Why an unmanaged thread in mono it freezes due to the garbage collector while using only fixed fields?
Thanks!
This is the pseudo-fuction
function_thread(){
fixed(my_fields){
while(true){
my_code_use_only_fixed_fields;
}
}
}
N.B.
The Mono runtime will automatically register all threads that are created from the managed world with the garbage collector. For developers embedding Mono it is important that they register with the runtime any additional thread they create that manipulates managed objects with mono_thread_attach. You can find this concept in this link
P.S. I suppose that the thread is not attached then the garbage collector does not know of its existence. I suppose this because I've not attached the thread.
While your unmanaged thread is running managed code, it will be affected by the GC just like any other thread. The current Mono (and MS.NET) GC doesn't allow GC to run concurrently with managed code at all (except perhaps finalizers). There's no analysis to figure out if it would be safe to run code concurrently. Note that there are differences based on the GC you're using (and the last time I checked Mono's GCs, they were still very basic - that has been a while ago, though), but to my knowledge, there will always be a point where every "user" thread is suspended. This isn't fundamental and could be changed in a custom GC, but it certainly isn't a simple problem, and it has very limited utility. If you want to avoid GC pauses, you must not use managed code.
And I also have to point out that using fixed like this will tend to prevent the GC from working correctly - anything that's fixed will be unavailable during heap compaction, which will result in either heap fragmentation or preventing GC from reclaiming any memory in the worst case.
In the MS .NET Runtime, unmanaged threads which access the runtime are automatically registered as managed threads. I would be surprised if Mono does this differently.
This behavior is documented here:
When an unmanaged thread enters the runtime ... the system checks the thread-local store of that thread to look for an internal managed Thread object. If one is found, the runtime is already aware of this thread. If it cannot find one, however, the runtime builds a new Thread object and installs it in the thread-local store of that thread.
That being said, if it is desired to have a pure GC-free thread, a pure unmanaged thread can be created which interacts with a 'runner' managed thread through standard asynchronous programming patterns, e.g., wait handles, shared memory, etc.
My windows service is using .Net managed objects like Sockets, Threads, Monitors, Semaphores. I have two questions related to these objects.
Do we have to implement IDisposable.Dispose on classes using above managed objects, to release them in order to assist when the service stops.
We also have threads waiting on monitors. If we don't stop/exit them before exiting does the Garbage collector clean them?
When you use IDisposables, you should dispose them somewhere. If they are references in fields, you usually need to implement IDisposable in that class and dispose it there. Threads should be stopped (using e.g. a reset event) and joined.
I am dealing with some legacy code that probably predates .NET 2. The library itself is custom asynchronous TCP communication layer used by our server.
There is a class there inheriting from System.Net.Sockets.TcpClient and the whole class hierarchy around it that implements dispose pattern and finalizers (the latter likely not needed).
My question is about suspicious line of code found in the method that handle TCP client disconnected event:
// Hack to ensure that client has disconnected
GC.Collect();
which is executed after calling methods disposing of our communication class hierarchy that eventually calls System.Net.Sockets.TcpClient Dispose method.
On a 64-bit server that can serve many clients and use gigabytes of RAM these calls can be quite expensive. I could not find anything about forcing garbage collection upon TCP client disconnection?
Two things will happen after you force GC with GC.Collect().
Memory used by unreachable objects that don't have finalizers will be reclaimed.
Objects that implement finalizers will be placed on finalizer queue, and the finalizers will be executed soon.
The comment suggests that GC.Collect() is not called to reclaim memory, but rather to execute finalizers to dispose unmanaged resources.
If IDisposable is used correctly, there is no need to rely on finalizers. Probably there are some IDisposable objects that are not Disposed correctly. You'll have to find them. One way to do it is to examine what finalizers are executed. Some memory profilers can also track such objects (for example .NET memory profiler's Dispose Tracker).
I want to access object without finalizer from finalizer of other instance.
I know that it is bad idea to access other finalizable object from finalizer because sequence of finalizer call is non-deterministic.
But what about accessing instances without finalizer from finalizer of other objects?
I can not figure out this, the only found in the article http://edn.embarcadero.com/article/29365 :
This means that finalizers should never access other finalizable
objects (objects without finalizers, however, are just fine)
Is any confirmation of this in MSDN?
Currently I want to acquire lock object with variable of type object but I want to be sure that it is ok and object instance is not freed from memory before accessing it.
Thanks
Currently I want to acquire lock object with variable of type object
Accessing that object in your finalizer is fine, nothing happened to it. Actually using it a lock statement, that's not so fine. Blocking the finalizer thread tends to byte badly. It has a time-out at program exit, it must complete and get everything finalized within two seconds. You cannot afford a Monitor.TryEnter() to avoid tripping that timeout, that will be a bad resource leak.
And beware the code smell, you should not be releasing whatever native resource you wrote the finalizer for when other threads can still access it. It is gospel that the finalizer can only run when nobody keeps a reference to the object anymore. Which should also mean that there shouldn't be any point in locking anymore since no thread could have a reference anymore. There is no need to protect shared state with a lock when nobody can read or write it.
Keep in mind that actually writing a finalizer tends to be almost always wrong, native resources should be finalized by their corresponding .NET wrapper class. There are many, the low-level ones are the SafeHandle derived classes.
Objects are not collected till the time they have a root. Assuming the object instance you are talking about is member of the object that is getting finalized, then that object has been alive all the time - because root is f-reachable queue.
However, I will strongly advise against any locking or blocking in finalizer. It could cause ugly deadlocks.
What guarantees are the for the garbage collector?
From my research I have managed to find:
If there is still a reference to the memory it will not be garbage collected
If there is no reference:
When it is GC is non deterministic
When the GC kicks in the finalizer will be run before memory is released.
There is no guarantee about the order of Finalizers (so do not assume parent will be run before child).
But what I really want to know is:
Is there a guarantee that all memory will eventually be garbage collected and the finalizer (destructor) run on the object (assuming the program exited nicely). For example an application with no memory pressure when it eventually exits will it force the GC to go find all objects and make sure the finalizer (destructor) is called (including static member variables)?
I did find a quote on this page:
http://www.c-sharpcorner.com/UploadFile/tkagarwal/MemoryManagementInNet11232005064832AM/MemoryManagementInNet.aspx
In addition, by default, Finalize methods are not called for unreachable objects when an application exits so that the application may terminate quickly.
But I am not sure how authoritative this quote is.
I also found documentation on:
CriticalFinalizerObject
Is there a guarantee that all memory
will eventually be garbage collected
and the finalizer (destructor) run on
the object (assuming the program
exited nicely).
No. From the Object.Finalize documentation it is clear that finalizers may not be invoked if
Some other finalizers don't finish properly:
Another finalizer blocks indefinitely
(goes into an infinite loop, tries to
obtain a lock it can never obtain and
so on). Because the runtime attempts
to run finalizers to completion, other
finalizers might not be called if a
finalizer blocks indefinitely.
Some other finalizers create more
finalizable objects, making it
impossible to finalize all
finalizable objects:
The runtime continues to Finalize
objects during shutdown only while the
number of finalizable objects
continues to decrease.
Some other finalizers throw exceptions:
If Finalize or an override of Finalize
throws an exception, and the runtime
is not hosted by an application that
overrides the default policy, the
runtime terminates the process and no
active try-finally blocks or
finalizers are executed. This behavior
ensures process integrity if the
finalizer cannot free or destroy
resources.
That being said, there are more reasons why you wouldn't want to use finalizers unless strictly necessary.
They slow down the garbage collector
(even making it possible to slow it
down so much that memory is not
reclaimed as fast as it is used up).
They run on another thread, bringing
multi-threading issues into play.
They're not executed in a
deterministic order.
They can resurrect objects which were
already finalized (and which won't be
finalized again unless explicitly
re-registered for finalization).
The only time you should write a finalizer is when you are building a type to handle a new kind of unmanaged resource. For example, a data access layer that uses Sql Server in a business app doesn't need a finalizer anywhere, even though there are unmanaged database connections involved, because the basic SqlConnection class will already finalize those connections if needed. But if you're building a brand new database engine from scratch that has connection limits similar to sql server's and are implementing the ado.net provider for it, that connection type should implement a finalizer to be as sure as possible that your connections are released.
But you don't get any guarantees beyond what happens when a process ends.
Update:
Given this context:
I am having a discussion with a collegue over a code review I did of his code. He insists that the destructor is guranteed to be called on an object. I disagree (but am not sure) and would prefer the use of IDisposable.
You are right to criticize the use of a destructor/finalizer. As I said above, you should only use them when working with an unmanaged resource that is genuinely new. Not just that instance of the resource, but the kind of resource you are working with.
For code that wraps "normal" unmanaged resources (things like SqlConnection, TcpClient, etc), IDisposable is a better choice. Then you know the resource will be cleaned up as soon as Dispose() is called rather than needing to wait for the type to be collected. If no one calls Dispose() (which is likely your colleague's concern), by the time your new type can be collected the instance of the original type for the unmanaged resource you are wrapping should be able to be collected as well, and it's finalizer will release the resource.
The main thing you need to bring to the table is that the finalizer cannot be called until the object is collected. You have to wait on the garbage collector, meaning you may be holding the resource open even longer. IDisposable allows you to release it right away. Of course you could do both, but that doesn't sound like what's going on here, and if you do have both you have to be careful not to conflict with the original type's finalizer or you could cause unwanted and harmful exceptions. And really, your own finalizer implementation is just redundant here and adds needless complexity.
Finally, I have to take issue with this statement:
If there is still a reference to the memory it will not be garbage collected
There can be references to an object and it will still be collected. What matters is if the object is reachable: are any of the references to the object rooted. For example, you may have a list with several objects in it. The list goes out of scope. Obviously there is still a reference to all of the objects in the list, but they can still all be collected in the first pass of the GC because the reference is no longer rooted.
1.6.7.6 of the Spec says:
1.6.7.6 Destructors
A destructor is a member that implements the actions
required to destruct an instance of a
class. Destructors cannot have
parameters, they cannot have
accessibility modifiers, and they
cannot be invoked explicitly. The
destructor for an instance is invoked
automatically during garbage
collection.
The garbage collector is
allowed wide latitude in deciding when
to collect objects and run
destructors. Specifically, the timing
of destructor invocations is not
deterministic, and destructors may be
executed on any thread. For these and
other reasons, classes should
implement destructors only when no
other solutions are feasible.
The
using statement provides a better
approach to object destruction.
So no, it's not guaranteed they are called.
The only time that a finalizer won't be invoked at all is if an AppDomain is forcibly unloaded.
In general, you don't need to worry about it.
There is no guarantee.
There might be a guarantee if your process terminates nicely for some definition of nicely. But there are so many things not nice that can happen:
power failure
process terminated in a 'hard' or 'forced' way
unmanaged thread throwing calling OS exit() function or throwing an exception
call to System.Environment.FailFast, which does:
MSDN: "Terminates a process but does not execute any active try-finally blocks or finalizers."