C#
has a unified type system in which all types, including primitive types inherit from object
type.
Java
also has all of its classes inherited from object
type.
Quote from Thinking in java
A singly rooted hierarchy makes it much easier to implement a garbage
collector
Does,unified type system
or single rooted hierarchy
help for doing Garbage collection and if so how?
I think the main reason is it helps ensure that all objects have a Finalize
method, thus enabling automatic compatibility with the GC.
This method is automatically called after an object becomes inaccessible, unless the object has been exempted from finalization by a call to GC.SuppressFinalize. During shutdown of an application domain, Finalize is automatically called on objects that are not exempt from finalization, even those that are still accessible. Finalize is automatically called only once on a given instance, unless the object is re-registered using a mechanism such as GC.ReRegisterForFinalize and GC.SuppressFinalize has not been subsequently called.
Well, you have a Problem here - you assume it helps because it makes the garbage collector better.
IT helps, because it can AVOID (!) garbage collection.
STRUCTS In C# - and that are all primitive types like int etc., but also all you create yourself - are NOT garbage collected UNLESS they are boxed (assigned to an object, then they get a wrapper).
This means I can make elements like a Point (with x and y as ints) has Zero Overhead in the garbage collector because it is not garbage collected.
Basically, in Java primitives are "Compiler hacks", in C# primitives are the "other side of the object hierarchy" that are structs, not classes.
So, the unified type System does not help the gargabe collector by being unified, itdoes so by not creating objects that are garbage collected in the first place.
This also leads - with generic Support - to efficient collections that do not have to Box every item. That is where things get nasty in Java as the runtime has no concept of a generics at Bytecode Level, so everything there is "object", while in C# a List is a separate type of List in Bytecode and optimized.
The only thing which a garbage collector needs is to be able to identify the size of an object and where the references in the object are (e.g. from the type)
Having one way of determining this, can make it much simpler.
What is unified in .NET is the means by which structure types and class types are defined. A structure definition
struct IntPair
{
public Int32 V1,V2;
}
defines two things. It defines a heap-object type IntPair
which derives from IntPair
, which in turn derives from Object
, and will behave like an object because it is one. It also defines a storage-location type IntPair
which will behave like a pair of integers stuck together with duct tape because it is a pair of integers stuck together with duct tape. While the heap object type derives from Object
, the storage-location type isn't an object and doesn't hold one either. It holds two integers--nothing more; nothing less.
The benefit of the unified type system is that it makes it easier for the garbage-collector to handle value types which contain reference-type fields. It is necessary for the GC to be able to with 100% certainty identify all reachable references that exist throughout the universe, including those that are fields of a value type. If class-type and value-type definitions use the same data structures, the procedure for determining the size of a class object and the offset to each field can also be used for determine size of a structure along with the offset of each nested field thereof. Having value types which don't happen to contain nested references use the same data structures doesn't particularly benefit the GC, but doesn't hurt anything either. Given that value types which do contain references need to be defined in a manner the GC knows about, it's easier to have all value types defined by the same means than to have those which references defined one way, and those which don't contain references defined another.