您的位置:首页 > 其它

通过SetWorkingSet减少内存使用(翻译)

2011-03-11 10:51 176 查看
第一次翻译文章,错误在所难免。让大家见笑了!还希望高手多指点。。

Windows Form应用程序在内存使用方面显得非常臃肿。主要是因为.NET应用程序在启动的时候有大量的footprint被JIT编译器加载,并且所有的链代码和WinForms引擎在启动时候被编译,并加载到程序的进程。这一过程占用了处理器时间片的同时也占用了大量的内存。JIT在确定哪些代码应该被编译已经做的非常好了,大部分其编译的代码都是事实上要用的。但是.NET框架本身也会要求编译一些代码。这样的结果就是程序进程加载了很多只在启动的时候才会用的资源。
如果你已经运行了你的程序,那在任务管理中你会发现其占用了很大的内存。基本上一个由TextBox和Button组成的典型WinForm程序要占用8M的内存。If you move the form around a bit closer to 10。(不知道这个怎么翻,:)你可以最小化窗口,那内存使用就会降下来,如果再重新打开,那内存又会慢慢提升。这个现象是因为程序内部调整了工作集的大小从而释放了一些资源。如果程序发现其需要部分不再内存中,那将会再次将该部分加载到内存中,但是内存占用还是会比一开始启动时候低很多。
对于.Net应用程序而言,这是一个非常有用的功能,因为大量启动过程中载入的资源被清掉。你可以强迫你的程序最小化再恢复窗口到原来状态来达到这个释放资源的效果,但是这个方法可能不是你在自己应用程序中希望看到的。那更好的方法就是在你的程序中调整工作集大小:

1 public static void SetWorkingSet(int lnMaxSize,int lnMinSize)
2
3 {
4
5 System.Diagnostics.Process loProcess = System.Diagnostics.Process.GetCurrentProcess();
6
7 loProcess.MaxWorkingSet = (IntPtr) lnMaxSize;
8
9 loProcess.MinWorkingSet = (IntPtr) lnMinSize;
10
11 //long lnValue = loProcess.WorkingSet; // see what the actual value
12
13 }
14

我已经在WinForm Load事件以及Deactivate事件中调用了这个静态方法。后者是一种欺骗行为。如果你再去到任务管理器中去查看内存使用那个情况,你就会发现内存使用量非常低。

1 private void frmWebStoreMain_Deactivate(object sender, System.EventArgs e)
2
3 {
4
5 wwUIRoutines.SetWorkingSet(750000,300000);
6
7 }
8

工作集的大小并不一定会减少到你设置的那个值,但Windows会尝试以尽可能减少。事实上在任务管理器中看到的内存使用也不是精确的,但我听说有些人用了这些方法后,减少了非常到内存使用量,他们对此感到惊讶不已。
比如说,网络监控程序无上述代码运行约14 - 15megs的内存。在应用了上述代码后(作为监控线程的一部分)内存使用量5-7 megs之间。网上商店用户端应用程序,没有使用上述代码,程序运行需要25 megs内存。使用上述代码后程序运行在7 10megs 。
从某种意义上讲,这是在欺骗应用程序—-但是这个的确能提高程序在这台机器中内存使用的印象。我认为,这个对实际性能(PC)影响不大,因为如果系统需要,内存无论如何都会被回收。但是对于那些以内存为衡量标准的人而言,这样做还是很有意义的。
请注意,这个行为是有一定开销的,也就说会影响性能。因为在释放了资源后,内存也被回收,但是如果程序再次需要这个资源时,那该部分将再次被加载到内存中,那这个过程就会对性能有一定的影响。因此要小心使用这个方法在需要高性能的程序中。

原文地址:http://www.west-wind.com/Weblog/posts/240.aspx
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: