C# Mono虚拟机是否可以跨进程共享?

C# Mono虚拟机是否可以跨进程共享?,c#,mono,C#,Mono,如果我想在Linux上的mono下运行两个或多个控制台应用程序,我会为每个进程产生mono虚拟机的开销,还是虚拟机的一部分会跨进程重用?如果不是这样,有没有办法共享mono虚拟机使用的部分内存 我希望实现以下目标:假设应用程序加载标准库的许多程序集时,mono虚拟机需要100MB。应用程序A的特性使其额外使用50Mb的RAM(因此进程A使用的RAM总量为150Mb),而应用程序B的特性使其额外使用120Mb的RAM(因此进程B使用的RAM总量为220Mb) 如果按照Mono的工作方式,将产生两个

如果我想在Linux上的mono下运行两个或多个控制台应用程序,我会为每个进程产生mono虚拟机的开销,还是虚拟机的一部分会跨进程重用?如果不是这样,有没有办法共享mono虚拟机使用的部分内存

我希望实现以下目标:假设应用程序加载标准库的许多程序集时,mono虚拟机需要100MB。应用程序A的特性使其额外使用50Mb的RAM(因此进程A使用的RAM总量为150Mb),而应用程序B的特性使其额外使用120Mb的RAM(因此进程B使用的RAM总量为220Mb)

如果按照Mono的工作方式,将产生两个独立的Mono虚拟机,那么我将使用370Mb的RAM。但是,如果基本库之类的内存在虚拟机之间共享,那么我只能使用100+50+120=270Mb的RAM

问题是,我可能会运行几十个或数百个相对较小的应用程序,我担心每个mono虚拟机保留的内存会大幅降低部署的内存占用,而每个应用程序的RAM需求实际上不会那么大。我说的是控制台应用程序(web服务)


谢谢

一如既往,视情况而定;-)

  • Linux将始终共享多次运行的相同可执行文件的只读段。即VM的可执行代码和常量数据在内存中只存在一次,而可变数据不共享

  • 但有一件事需要知道。由于Mono是一个即时编译器,它会将IL语言转换为您平台的本机代码。你的问题开始了翻译后的代码在运行时生成并驻留在非只读内存段中。内核不再知道这种冗余,因此mono类库占用的内存将不会在同一主机上运行的mono VM之间共享。
    (事实上,内存页无论如何都不会完全匹配,因为不同的VM可能运行稍有不同的代码路径,例如,以不同的顺序加载运行时的类或类似的东西。)

  • 如果这是故事的结局,事情会很容易,但事实并非如此。还有另一个Mono功能:AOT(提前编译)
    在这种情况下,ode不会在运行时由JIT编译成机器语言。相反,之前已经预编译了。在这种情况下,从VMs实例的角度来看,预编译代码是只读的。现在,内核将再次将预编译代码作为常量数据共享。

  • 但这还不是故事的结局AOT编译器确实支持Mono的所有功能,但它有一些限制。它不能处理所有的程序模式。因此,一些运行时类是不共享的。详细信息取决于Mono版本以及您的平台。
    有关更多详细信息,请参阅

  • 所以答案并不那么容易。根据Mono版本以及引用的库是否包含平台的预编译代码,并发运行的VM之间会共享更多或更少的内存

    实际上,它将介于你的悲观假设和乐观假设之间。您可以非常肯定,即使AOT做得非常好,VM的某些数据段也无法共享。例如,内部变量和类实例(如反射类)将不会共享。
    AOT只覆盖IL代码,但不涉及仅依赖于设计时间常数的表达式和对象,如C++代码> CONTXPRPR < /C> > 我不知道它在您的特定用例中是如何扩展的。但您所说的是数百个相对较小的应用程序。小型应用程序很可能不会有100 MB的运行时开销。至少我不会再称之为“小应用程序”


    但还有一个建议:不要启动数百个并行进程。即使Mono虚拟机在内存共享方面做得很好,这也是对系统资源的过度使用。使用队列将任务委托给数量有限的进程,或者以其他方式重新思考您的概念。很可能会遇到非线性的可伸缩性和糟糕的最坏情况性能