据我所知,在.NET 4.0之前,事情很简单:一个进程只能托管一个CLR.
但是从版本4.0开始,一个进程可以托管多个CLR.
在这种情况下,我猜每个CLR有一个堆,因为每个CLR都有自己的状态和自己的GC,它有自己管理内存和自己的收集周期的方式,所以共享内存似乎是不可能的.
1)你能否确认这是最终的情况还是更微妙?
2)两个CLR是否在同一个过程中被严格隔离,还是可以分享?(特别是如果他们有相同的版本,他们可以互相了解)
我想答案是肯定的和是(孤立的),但我想确定.
感谢您的任何见解.
我们需要的第一件事是整理或绘制一般情况下正在发生的事情:
\n\n您执行 exe 文件 -> 该文件要求 .NET CLR -> CLR 进程 - 托管您的执行。
\n\n为了简单起见,我将把它写得更短:
\n\n这是 4.0 之前发生的情况:
\n执行 File1.exe -> CLR Process ->hosts (.net File1.exe) => 这里我假设 file1.exe 是 .net1
\n执行 File2.exe -> CLR Process2 - > 主机(.net File2.exe)=>这里我假设file2.exe是.net2
\n执行 File3.exe -> CLR Process3 -> ports (.net File3.exe) => 这里我假设 file3.exe 是 .net3
在上面的示例中,我假设计算机上安装了 .net 3,这就是为什么 .net3 CLR 是该进程 - 确实如此 - 它被加载了 3 次!然而,由于 DLL 是同一个 DLL,因此窗口可能会共享它,使其就像只加载了一次一样。但在内存中 - 使用 3 个不同的指令指针,并且每个进程都有自己独立的堆。
\n\n这就是 4.0 和 4.5 中发生的情况:
\n执行 File4.exe -> CLR Process45 -> 主机 (.net File4.exe) =>这里我假设 file4.exe 是 .net4
\n执行 File45.exe -> CLR Process45 - > 还托管(.net File45) => 这里我假设 file45.exe 是 .net4.5
在上面的示例中,我假设计算机上安装了 .net 45,因此 .net CLR4 是仅加载一次的进程(而不是两次!正如前面示例逻辑所预期的那样)
\n\n您可以在我的答案末尾提供的链接中阅读更多内容,以了解哪些版本可以“坐在”在一起 - 并非所有版本都可以与所有版本并排放置。
\n\n我的答案的第二部分与您的确切要求更相关:
\n任何进程都有一个堆 - 无法更改,因为它是硬件的工作方式。
(不管 CLR 从这个意义上来说只是另一个进程可以做什么)
\n但是为了能够为托管的每个 exe 提供一个堆,他们发明了一个名为“blob-heap”的概念,它被放置在 CLR 的堆中过程。可以同时管理如此多的 blob 堆。
\nCLR 中的每个托管应用程序都有自己的 GC,并且它们是隔离的并且彼此不知道。
\n据我了解,.NET4 中仅使用一个 CLR,它能够管理许多主机项或应用程序。这意味着许多应用程序可能会相互减慢速度,但即使使用“多 CLR”方法,情况也是如此。更严重的问题是,如果 CLR 本身停止运行...所有托管应用程序都将停止运行它。我不知道架构中如何或是否解决了这种潜在问题。
我从所有这些来源中阅读了这个答案:
\n公共语言运行时 (CLR)
\n ECMA C# 和公共语言基础设施标准
\n公共语言基础设施 (CLI) 分区 I 到 VI(第 6 版)
\n进程内端并行
\n加载多个 CLR 运行时 (InProc SxS) \xe2\x80\x93 示例代码