每个 CLR 或每个进程是不是有一个托管堆?
Posted
技术标签:
【中文标题】每个 CLR 或每个进程是不是有一个托管堆?【英文标题】:Is there one managed heap per CLR or per process?每个 CLR 或每个进程是否有一个托管堆? 【发布时间】:2013-10-22 12:33:06 【问题描述】:据我所知,在 .NET 4.0 之前,事情很简单:一个 进程 只能托管一个 CLR。
但从 4.0 版开始,一个进程可以承载多个 CLR。
在这种情况下,我猜每个 CLR 有一个堆,因为每个 CLR 都有自己的状态和自己的 GC,有自己的内存管理方式和自己的收集周期,所以共享内存似乎是不可能的。
1) 您能否确认这是最终的情况还是更微妙?
2) 托管在同一个进程中的两个 CLR 是严格隔离的还是可以共享任何东西? (特别是如果他们有相同的版本,他们是否可以互相了解)
我猜答案是肯定的和肯定的(孤立的),但我想确定一下。
感谢您的任何见解。
【问题讨论】:
见***.com/a/6982447/56778 @JimMischel:如果这是来自 Skeet 大师,那一定是真的。 :) 太糟糕了,您指向的讨论没有被正确标记,所以我会找到它。我已经更新了它的标签。谢谢:) @JimMischel:仍然是隔离问题... :) Google 在查找未标记的内容方面做得很好。 【参考方案1】:我们需要做的第一件事是整理或映射总体上正在发生的事情:
您执行您的 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 Process3 -> hosts (.net File3.exe) =>这里我假设 file3.exe 是 .net3
在上面的示例中,我假设机器上安装了 .net 3,这就是为什么 .net3 CLR 是进程 - 确实 - 它被加载了 3 次!但是,由于 DLL 是相同的 DLL,因此 Windows 可能会共享它,就好像它只加载了一次一样。但在内存中 - 使用了 3 个不同的指令指针,每个进程都有自己独立的堆。
这就是 4.0 和 4.5 发生的情况: 执行 File4.exe -> CLR Process45 -> hosts (.net File4.exe) =>这里我假设 file4.exe 是 .net4 执行 File45.exe -> CLR Process45 -> also hosts (.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 StandardsCommon Language Infrastructure (CLI) Partitions I to VI (6th edition)In-Process Side-by-SideLoading multiple CLR Runtimes (InProc SxS) – Sample Code
【讨论】:
以上是关于每个 CLR 或每个进程是不是有一个托管堆?的主要内容,如果未能解决你的问题,请参考以下文章