Rob*_*ser 107 .net c# memory optimization memory-optimization
有哪些提示可以减少.NET应用程序的内存使用量?考虑以下简单的C#程序.
class Program
{
    static void Main(string[] args)
    {
        Console.ReadLine();
    }
}
在x64的发布模式下编译并在Visual Studio外部运行,任务管理器报告以下内容:
Working Set:          9364k
Private Working Set:  2500k
Commit Size:         17480k
如果它只为x86编译它会好一点:
Working Set:          5888k
Private Working Set:  1280k
Commit Size:          7012k
然后,我尝试了以下程序,它执行相同但尝试在运行时初始化后修剪进程大小:
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 发布上的结果:
Working Set:          2300k
Private Working Set:   964k
Commit Size:          8408k
哪个好一点,但对于这样一个简单的程序来说似乎仍然过分.是否有任何技巧可以使C#流程更精简?我正在编写一个旨在大多数时间在后台运行的程序.我已经在单独的应用程序域中执行任何用户界面操作,这意味着可以安全地卸载用户界面的东西,但是当它只是坐在后台时占用10 MB似乎过多.
PS至于为什么我会关心---(Power)用户往往担心这些事情.即使它对性能几乎没有影响,半精通技术的用户(我的目标受众)倾向于对背景应用程序内存使用情况进行调整.当我看到Adobe Updater占用11 MB的内存并且感受到Foobar2000的平静触摸时,即使我玩的时候也可以拿到6 MB以下,我甚至会感到蠢蠢欲动.我知道在现代操作系统中,这些东西在技术上并不重要,但这并不意味着它对感知没有影响.
Bri*_*sen 44
与本机应用程序相比,.NET应用程序占用的空间更大,因为它们都必须在流程中加载运行时和应用程序.如果你想要一些非常整洁的东西,.NET可能不是最好的选择.
但是,请记住,如果您的应用程序主要处于休眠状态,那么必要的内存页面将被换出内存,因此在大多数情况下不会对系统造成太大的负担.
如果您想要缩小占用空间,则必须考虑内存使用情况.以下是一些想法:
List<T>并在需要时将容量增加一倍,因为它们可能导致50%的浪费.无论如何,这可能不是一个详尽的清单,而只是一些想法.
Joh*_*udy 33
我不会说你应该忽略你的应用程序的内存占用 - 显然,更小,更高效往往是可取的.但是,您应该考虑您的实际需求.
如果您正在编写一个标准的Windows窗体和WPF客户端应用程序,这些应用程序注定要在个人的PC上运行,并且很可能是用户操作的主要应用程序,那么您可以通过更加缺乏内存分配来实现.(只要这一切都被解除分配.)
但是,为了解决这里不想担心的人:如果你正在编写一个将在终端服务环境中运行的Windows窗体应用程序,在可能由10个,20个或更多用户使用的共享服务器上,那么是,你绝对必须考虑内存使用情况.你需要保持警惕.解决这个问题的最佳方法是使用良好的数据结构设计,并遵循有关何时以及分配的最佳实践.
Jar*_*Par 16
在这种情况下,您需要考虑的一件事是CLR的内存成本.每个.Net进程都会加载CLR,因此会考虑内存因素.对于这样一个简单/小程序,CLR的成本将主导您的内存占用.
构建一个真实的应用程序并查看与该基准程序的成本相比的成本将更具指导性.
本身没有具体的建议,但您可以查看CLR Profiler(从Microsoft免费下载).
安装完毕后,请查看此操作方法页面.
从方法到:
本方法向您展示如何使用CLR Profiler工具调查应用程序的内存分配配置文件.您可以使用CLR Profiler来识别导致内存问题的代码,例如内存泄漏和过多或低效的垃圾回收.