As far as I know, before .NET 4.0 things were simple: one process could only host one CLR.
But from version 4.0 a process can host more than one CLR.
In this case, I guess there is one heap per CLR, because each CLR has its own state and its own GC with its own way of managing memory and its own collection cycles, so sharing memory just seems impossible.
1) Could you confirm that this is conclusively the case or is it more subtle?
2) Are two CLR's hosted in the same process strictly isolated or can they share anything?
(particularly if they have the same version, could they be aware of each other)
I guess the answers are yes and yes (isolated), but I'd like to be sure.
Thanks for any insight.
The first thing we need - is to sort out or map what is happening in a general:
you execute your exe file -> the file asks for a .NET CLR -> the CLR Process - hosts your execution.
So to be brief, I'll draw it shorter:
This is what was happening in previous to 4.0:
Execute File1.exe -> CLR Process -> hosts (.net File1.exe) => here I assume file1.exe is .net1
Execute File2.exe -> CLR Process2 -> hosts (.net File2.exe) => here I assume file2.exe is .net2
Execute File3.exe -> CLR Process3 -> hosts (.net File3.exe) =>here I assume file3.exe is .net3
In the above examples I assume .net 3 is installed on the machine and that is why .net3 CLR is the process - and true - it was loaded 3 times! however since the DLL is the same DLL windows may share it making it as if it was loaded just once. but in memory - 3 different instruction pointers are used on it and each process has its own separated heap.
And this is what happening with 4.0 and 4.5:
Execute File4.exe -> CLR Process45 -> hosts (.net File4.exe) =>here I assume file4.exe is .net4
Execute File45.exe -> CLR Process45 -> also hosts (.net File45) =>here I assume file45.exe is .net4.5
In the above examples I assume .net 45 is installed on the machine, so .net CLR4 is the process which was loaded just once (and not twice! as would expected from previous examples logic)
You can read more in the links I provide in the end of my answer to learn what versions can "sit" together - not all version can sit side by side with all versions.
The second part of my answer is of more relevancy to what you ask in exact:
Any Process has a single heap - that can not be changed as it is how the hardware works.
(regardless of what CLR which is just another process in that sense can do)
But in order to be able to provide a heap per exe being hosted they invented a concept named "blob-heap" Which is placed in the heap of the CLR process. so many blob heaps can be managed at once.
Each hosted app in the CLR has its own GC and they are Isolated and do not aware of each other.
To my understanding just a single CLR is being used in .NET4 which is able to manage many host items or apps. This implies that many apps will slow down each other in potential but that was true even if "Multi-CLR" approach were used instead.. the more acute problem is that if CLR itself stopped running... all hosted apps would stop running with it. I have no idea how or if that kind of potential problem is solved in the architecture.
I read from all those sources to assemble this answer:
Common Language Runtime (CLR)
ECMA C# and Common Language Infrastructure Standards
Common Language Infrastructure (CLI) Partitions I to VI (6th edition)
In-Process Side-by-Side
Loading multiple CLR Runtimes (InProc SxS) – Sample Code