据我所知,在 .NET 4.0 之前,事情很简单:一个进程只能托管一个 CLR 。
但是从版本4.0开始,一个进程可以承载多个CLR。
在这种情况下,我想每个CLR的都有一个堆,因为每个CLR都有自己的状态和自己的GC,以及自己的内存管理方式和收集周期,因此共享内存似乎是不可能的。
1)您能否确定确实是这种情况或更微妙?
2)在同一进程中托管的两个CLR是否严格隔离或可以共享任何东西?
(特别是如果它们具有相同的版本,他们是否可以彼此了解)
我猜答案是肯定的(是孤立的),但是我想确定。
感谢您的任何见解。
最佳答案
我们需要做的第一件事-整理或映射一般情况:
您执行exe文件->该文件要求.NET CLR-> CLR进程-托管您的执行。
简而言之,我将其缩短:
这是4.0之前的版本:
执行File1.exe-> CLR进程->主机(.net File1.exe)=>这里我假设file1.exe是.net1
执行File2.exe-> CLR Process2->主机(.net File2.exe)=>这里我假设file2.exe是.net2
执行File3.exe-> CLR Process3->主机(.net File3.exe)=>这里我假设file3.exe是.net3
在上面的示例中,我假定在计算机上安装了.net 3,这就是.net3 CLR是进程的原因-的确,它被加载了3次!但是,由于DLL是相同的,因此DLL窗口可以共享它,就好像它只被加载了一次一样。但是在内存中-在其上使用了3个不同的指令指针,每个进程都有自己独立的堆。
这就是4.0和4.5的情况:
执行File4.exe-> CLR Process45->主机(.net File4.exe)=>这里我假设file4.exe是.net4
执行File45.exe-> CLR Process45->还托管(.net File45)=>这里我假设file45.exe是.net4.5
在上面的示例中,我假定在计算机上安装了.net 45,因此.net CLR4是仅被加载一次的进程(而不是两次加载!如先前示例逻辑所预期的那样)。
您可以在我答案的结尾处提供的链接中了解更多信息,以了解哪些版本可以一起“坐下”-并非所有版本都可以与所有版本并排放置。
我的答案的第二部分与您确切要求的内容更为相关:
任何进程都有一个堆-由于硬件的工作方式,不能更改。 (无论从哪种意义上讲,CLR只是另一个过程都可以执行)
但是,为了能够为托管的每个exe提供堆,他们发明了一个名为“blob-heap”的概念,该概念被放置在CLR进程的堆中。因此可以一次管理许多Blob堆。
CLR中的每个托管应用程序都有其自己的GC,并且它们是隔离的,彼此之间不了解。
据我了解,.NET4仅使用一个CLR,它可以管理许多主机项或应用程序。这意味着许多应用程序之间的相互影响会减慢速度,但是即使使用“Multi-CLR”方法也是如此。.更严重的问题是,如果CLR本身停止运行,则所有托管应用程序都将停止运行。它。我不知道在架构中如何或是否解决了这种潜在问题。
我从所有这些来源阅读来汇编此答案:
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
关于.net - 每个CLR或每个进程有一个托管堆吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19368780/