每个CLR或每个进程是否有一个托管堆?

时间:2013-10-14 20:31:49

标签: .net heap clr

据我所知,在 .NET 4.0 之前,事情很简单:一个进程只能托管一个 CLR

但是从版本4.0开始,一个进程可以托管多个CLR。

在这种情况下,我猜每个CLR 有一个堆,因为每个CLR都有自己的状态和自己的GC,它有自己管理内存和自己的收集周期的方式,所以共享内存似乎不可能。

1)你能确认这是最终的情况还是更微妙?

2)两个CLR是否在同一个过程中被严格隔离,还是可以分享? (特别是如果它们具有相同的版本,他们是否可以彼此了解)

我猜答案是肯定的和是(孤立的),但我想确定。

感谢您的任何见解。

1 个答案:

答案 0 :(得分:2)

我们需要的第一件事就是整理或绘制一般情况:

执行你的exe文件 - >该文件要求.NET CLR - > CLR流程 - 托管您的执行。

简而言之,我会缩短它:

这是4.0之前发生的事情: 执行File1.exe - > CLR过程 - > hosts(.net File1.exe)=>在这里我假设file1.exe是.net1
执行File2.exe - > CLR Process2 - > hosts(.net File2.exe)=>在这里我假设file2.exe是.net2
执行File3.exe - > CLR过程3 - > hosts(.net File3.exe)=>这里我假设file3.exe是.net3

在上面的例子中,我假设.net 3安装在机器上,这就是为什么.net3 CLR是进程 - 而且是真的 - 它被加载了3次!但是因为DLL是相同的DLL,Windows可以共享它,就像它只加载一次一样。但是在内存中 - 它上面使用了3个不同的指令指针,每个进程都有自己独立的堆。

这就是4.0和4.5发生的事情: 执行File4.exe - > CLR过程45-> hosts(.net File4.exe)=>这里我假设file4.exe是.net4
执行File45.exe - > CLR Process45 - >还有主机(.net File45)=>这里我假设file45.exe是.net4.5

在上面的示例中,我假设.net 45安装在机器上,因此.net CLR4是仅加载一次的过程(而不是之前的示例逻辑所预期的两次!)

您可以在我的答案结尾处阅读我提供的链接中的更多信息,以了解哪些版本可以" sit"在一起 - 并非所有版本都能与所有版本并排放置。

我的答案的第二部分与你所要求的内容更为相关:
任何进程都有一个堆 - 无法更改,因为它是硬件的工作方式。
(无论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