首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >减少.NET应用程序的内存使用?

减少.NET应用程序的内存使用?
EN

Stack Overflow用户
提问于 2009-08-28 03:40:57
回答 9查看 75K关注 0票数 109

减少.NET应用程序内存使用的一些技巧是什么?考虑下面这个简单的C#程序。

代码语言:javascript
复制
class Program
{
    static void Main(string[] args)
    {
        Console.ReadLine();
    }
}

在适用于x64release模式下编译,并在Visual Studio外部运行,任务管理器报告以下内容:

代码语言:javascript
复制
Working Set:          9364k
Private Working Set:  2500k
Commit Size:         17480k

如果只为x86编译,效果会更好一些

代码语言:javascript
复制
Working Set:          5888k
Private Working Set:  1280k
Commit Size:          7012k

然后,我尝试了以下程序,该程序执行相同的操作,但会在运行时初始化后尝试调整进程大小:

代码语言:javascript
复制
class Program
{
    static void Main(string[] args)
    {
        minimizeMemory();
        Console.ReadLine();
    }

    private static void minimizeMemory()
    {
        GC.Collect(GC.MaxGeneration);
        GC.WaitForPendingFinalizers();
        SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle,
            (UIntPtr) 0xFFFFFFFF, (UIntPtr)0xFFFFFFFF);
    }

    [DllImport("kernel32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool SetProcessWorkingSetSize(IntPtr process,
        UIntPtr minimumWorkingSetSize, UIntPtr maximumWorkingSetSize);
}

在Visual Studio之外的x86 Release上的结果:

代码语言:javascript
复制
Working Set:          2300k
Private Working Set:   964k
Commit Size:          8408k

这是好一点,但对于这样一个简单的程序来说,它似乎仍然是多余的。有什么技巧可以让C#流程更精简一些吗?我正在写一个程序,它被设计成在大多数时间在后台运行。我已经在一个单独的Application Domain中做任何用户界面的东西了,这意味着用户界面的东西可以安全地卸载,但是当它只是坐在后台时占用10兆MB似乎太多了。

P.S.问我为什么会关心--(高级)用户倾向于担心这些事情。即使它对性能几乎没有影响,但半精通技术的用户(我的目标受众)往往会对后台应用程序的内存使用感到恼火。甚至当我看到Adobe Updater占用了11兆字节的内存,并被Foobar2000令人平静的触摸所安慰时,甚至我都抓狂了,即使在玩的时候,它也可以占用6兆字节的内存。我知道在现代操作系统中,这些东西在技术上并不重要,但这并不意味着它不会对感知产生影响。

EN

回答 9

Stack Overflow用户

回答已采纳

发布于 2009-08-27 20:00:30

  1. 你可能想要查看堆栈溢出问题.
  2. The MSDN博客文章
    1. 都是关于揭开工作集、进程内存的神秘面纱,以及如何对内存总消耗执行准确的计算。

我不会说您应该忽略应用程序的内存占用--显然,更小、更高效的应用程序确实是可取的。然而,你应该考虑你的实际需求是什么。

如果您正在编写一个标准的Windows窗体和WPF客户端应用程序,该应用程序注定要在个人的PC上运行,并且很可能是用户操作的主要应用程序,那么您可以对内存分配采取更懒惰的态度。(只要全部被释放即可。)

但是,这里有些人说不用担心:如果您正在编写一个Windows窗体应用程序,该应用程序将在终端服务环境中运行,在一个可能由10个、20个或更多用户使用的共享服务器上运行,那么,是的,您绝对必须考虑内存使用情况。你需要保持警惕。解决这个问题的最佳方法是进行良好的数据结构设计,并遵循有关何时分配和分配什么的最佳实践。

票数 34
EN

Stack Overflow用户

发布于 2009-08-27 19:44:37

与本机应用程序相比,.NET应用程序将拥有更大的内存占用空间,因为它们都必须在进程中加载运行时和应用程序。如果你想要真正整洁的东西,.NET可能不是最好的选择。

但是,请记住,如果您的应用程序主要处于休眠状态,则所需的内存页将被换出内存,因此在大多数情况下不会对系统造成太大的负担。

如果您希望保持较小的内存使用量,则必须考虑内存使用情况。这里有几个想法:

  • 可减少对象数量,并确保不会超过所需时间持有任何实例。
  • 要注意List<T>和类似的类型,它们会在需要时将容量加倍,因为它们可能会导致高达50%的浪费。
  • 您可以考虑使用值类型而不是引用类型来在堆栈上强制使用更多内存,但请记住,默认堆栈空间只有1 MB。
  • 避免使用超过85000字节的对象,因为它们将进入未压缩的LOH,因此很容易被碎片。

无论如何,这可能不是一个详尽的列表,而只是一些想法。

票数 46
EN

Stack Overflow用户

发布于 2009-08-27 19:45:01

在这种情况下,您需要考虑的一件事是CLR的内存成本。为每个.Net进程加载CLR,并因此将其纳入内存考虑因素。对于这样一个简单/小的程序,CLR的成本将主宰您的内存占用。

与这个基准程序的成本相比,构建一个真实的应用程序并查看其成本会更有指导意义。

票数 17
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1343374

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档