【问题标题】:Shared memory and runnning multiple copies of an executable共享内存并运行可执行文件的多个副本
【发布时间】:2009-06-21 13:55:37
【问题描述】:

我有一个应用程序(winform exe),我运行了几次。这是否意味着我有共享程序集或者每个实例都有自己的程序集副本?当我运行该应用程序时,它使用了大约 30MB(在任务管理器中),而当我运行该应用程序的另一个副本时,它又使用了 30MB。

如何计算它使用了多少内存,以及如果我运行多个实例,是否可以减少内存的过度使用?

问候 京东。

【问题讨论】:

  • 是静态链接还是动态链接?

标签: c#


【解决方案1】:

这很复杂。

首先阅读我最近关于虚拟内存的文章。

http://blogs.msdn.com/ericlippert/archive/2009/06/08/out-of-memory-does-not-refer-to-physical-memory.aspx

好的,现在您对虚拟内存的工作原理有了一些了解,您可以了解操作系统如何将 DLL 加载到内存中。假设您有两个进程都需要 Foo.DLL 的特定页面。操作系统会将该页面加载到物理内存一次,然后将该物理页面映射到两个进程的虚拟空间中。因此,正在使用的物理内存量是 4KB 页。但是这 4KB 出现在两个进程中。您的 30MB 中的大部分很可能是共享物理内存。

找出方法是更复杂地了解您对任务管理器的使用。您想在那里添加一些列并查看“工作集”和“私有工作集”。 “工作集”是该进程当前使用的私有和共享页面的总数。 “Private Working Set”是未共享的数量。

要降低内存使用量——首先,首先要了解您关心的原因。这些天机器有足够的内存,而 30MB 是一个相对较小的内存量。除非你能找到一个令人信服的以客户为中心的理由来解决这个问题,否则就去做其他事情,比如让你的程序更快或添加更多功能。假设您确实有理由关心,请为自己准备一些工具——尤其是内存分析器。 .NET 内存分析器可以告诉您所有分配在哪里以及它们有多大。

【讨论】:

    【解决方案2】:

    如果您没有静态资源,您可以在应用程序启动并且它的实例已经存在时添加一个新线程,而不是使用第二个进程。这就是 Firefox 所做的。

    【讨论】:

    • 这是个好主意。会有一些额外的内存使用,但少于应用程序的完整副本。
    【解决方案3】:

    当您注意到运行应用程序的第二个副本使用另外 30MB 内存时,我认为您已经回答了自己的问题。

    您的应用程序的每个实例都将在其自己的进程空间中运行,并且不会与应用程序的任何其他实例共享内存或非文件资源。

    在不知道您的应用程序做什么的情况下,我能想到的(目前)减少它使用的内存量的唯一方法是将数据写入磁盘。当这些对象超出范围时,这将释放内存 - 但当您从磁盘读回数据时显然会被重用。

    【讨论】:

    • 感谢克里斯的快速回复。在 GAC 中注册使用的程序集怎么样。这会有帮助吗?
    • 我不这么认为 - 但我还没有真正深入研究 GAC,因为我没有必要,所以我不能肯定地说。
    • 不,它们仍然必须加载到进程的内存中。此外,您当前在 WinForms 应用程序中使用的大多数程序集可能已经在 GAC 中。
    • 您忽略了 Windows 具有虚拟内存系统的事实。共享磁盘映像只会被加载到物理内存一次,然后这些物理页面将被映射到每个进程的虚拟内存中。
    猜你喜欢
    • 2014-10-06
    • 1970-01-01
    • 1970-01-01
    • 2016-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-18
    • 1970-01-01
    相关资源
    最近更新 更多