20070529 .NET 程序 内存 占用 SetProcessWorkingSetSize
 http://www.yippeesoft.com
 
SaferRun大概内存14M。虚拟内存同样14
减少.Net程序的内存空间占用的方法

MSDN 对该函数的表述(翻译):使用这个函数来设置应用程序最小和最大的运行空间,只会保留需要的内存。当应用程序被闲置或系统内存太低时,操作系统会自动调用这个机制来设置应用程序的内存。应用程序也可以使用 VirtualLock 来锁住一定范围的内存不被系统释放;当你加大运行空间给应用程序,你能够得到的物理内存取决于系统,这会造成其他应用程序降低性能或系统总体降低性能,这也可能导致请求物理内存的操作失败,例如:建立 进程,线程,内核池,就必须小心的使用该函数。
    也就是说,该函数不是节省内存,而是强制把进程的物理内存搬到虚拟内存中。
    另外有一些资料上说,该函数“将有可能导致缺页中断,严重影响性能”。

    Windows编程里有个方法叫做SetProcessWorkingSetSize,对编程有所了解的可以搜索一下。这个方法能够设定程序所占用的内存数(当然有一个最小值)。

比如你打开一个程序,把它最小化,再看任务管理器,里面占用的内存数就是它所使用的最小值,其他暂时用不到的代码就被放到了虚拟内存里。但是,这样做,是影响性能Windows把最多的内存分配给了前台正在运行的程序。

而天气秀等软件所号称的内存压缩技术,就是调用这个SetProcessWorkingSetSize,把内存中的程序代码放到虚拟内存里,调用一次还不够,因为程序运行内存占用不停变化。所以要设定一个Timer(计时器),每隔一段时间就调用一次(通常是几毫秒)。

虚拟内存是指硬盘上的一部分空间。也就是说,当这些软件运行时,每隔几毫秒,你的电脑CPU就要强制把内存中的代码放到硬盘上--往硬盘不停地写。
说实话,这种方式来实现内存占用少(实际上并没有少)很BT。

.NET   的内存管理机制中有一点,如果物理内存较大的话,GC   回收的比较懒,相反就比较勤。 
  
  如果你想要使用内存的指标好看一些,适时调用一下   GC.Collect(2),这会让运行的程序的内存使用量看起来会少很多。 
  
  另外,打开了窗口,你马上最小化一次看看,内存量是不是马上降下来了?即使再还原了窗口,内存也不是很多。但随着执行的继续,可能内存量又会上来,再最小化一次,又降下去了。运行过程如果涉及了大量的运算后,建议使用一下   GC.Collect   方法,这仅是为了好看一些。其实没这个必要的。 
  
  .NET   中,内存用量可能是要相对多一点,但这不是什么缺点。.NET   的内存管理机制是优秀的、卓越的。

  C# WinForm内存占用问题讨论
    分类:ASP.net & C#时间:2007-2-9 11:09:17作者:Carrod

      自开始学C#以来发现WinForm启动后占用内存较大,小小100KB的程序就用了15MB左右,这是为什么?可能以下几个原因:
      1、首先,C#的运行环境.Net Framework要调到内存中去。
      2、JIT程序通常需要一个相对比较大的启动工作集(但是当程序稳定以后,需要的内存并不多)。
      3、IDE中运行该WinForm。

      解决方法在《.NET Framework自动内存管理机制深入剖析(C#分析篇)》一文中提到过,但.net的垃圾回收机制似乎有点懒,如果运行环境的内存充足再回收工作不够勤;相反内存较紧、容易达到峰值则会较快地去回收。可以试试下面的解决方案:
      1、Debug/Release,尝试使用Release Build。
      2、不要在IDE中运行。
      3、必须的资源要及时dispose。
      4、调用System.GC.Collect() 强制回收。
      5、若可以,将对象赋值为null。

      参考:
    int[] obj = new int[10000];
      ….
      obj = null;
      System.GC.Collect();

      补充一点:进程管理器里面看到的内存状况并不能反映你的程序实际使用的内存,因为进程管理器不能理解.net程序的GC机制。正确的方法是使用Performance Monitor监视.NET程序的内存状况。

      忘记说一点了,把运行的程序(原本占20MB内存)最小化到任务栏(此时内存占用将有可能降至1MB甚至更低,当然,似乎是内存管理将该程序占用的内存暂时转移到其他运行中的程序去了。还有种说法是保留在虚拟内存)再还原,占用内存量大大降低了,大概在6MB左右。

我做的.net程序,一般只有几个控件,结果启动时就占用内存20M左右(任务管理器中查看),我知道这个数据不准确。但是别的语言写的比如delphi启动后显示就只有几M。 
  而且我发现.net程序启动很慢,有人说是因为.net   程序启动时要加载整个平台,不知道这种说法对不?

  要加载CLR,还有那些用到了的dll(不是所有dll),已经就很大了 
  内存占用的问题是没有办法的 
  Java程序也一样(Eclipse   IDE的内存占用动不动就上百兆)

  利用下面的方式控制内存大小(这是C#,请自行翻译成vb.net语言,我是转载的,不过的确好用): 
  
  .net中内存占用的问题 
  
  今天开始解决系统占用内存过大的问题。 
  
  在去年做系统的时候,就发现系统占用内存大,到今年6月,系统启动后占用内存达到60M,运行一段时间后达到100M左右(任务管理器监视的结果),到时想各种办法都没有解决(包括GC.Collect、析构函数等),后来和灵感之源在MSN上讨论了一下,他认为可能是系统中使用MagicLibrary 的问题,因此也就搁置下来。   
  
  刚才在网上查到博客堂上也有人进行过讨论,知秋一叶作了精彩的解释,看了之后有茅塞顿开之感。在系统中使用 SetProcessWorkingSetSize方法做了一个测试,调用该方法后,占用内存从80M降到2M.(TaskManager观察的结果)按照知秋一叶的说法,这样调整WorkingSet,将有可能导致缺页中断,严重影响性能。   但是从使用的情况来看,没有发现这样的现象,这可能是我使用这个方法的原因:   
  
  
  public   static   int   MinOf(uint   pID)       
                  &leftsign;     
                          IntPtr   hd   =   OpenProcess((uint)PROCESS_ACCESS_RIGHTS.PROCESS_SET_QUOTA,   false,   pID);     
                              
                          try       
                          &leftsign;     
                                  if   (hd   !=   IntPtr.Zero   &&   System.Environment.OSVersion.Platform   ==   System.PlatformID.Win32NT)       
                                  &leftsign;     
                                          return   SetProcessWorkingSetSize(hd,   -1,   -1);     
                                  &rightsign;     
                                  else       
                                  &leftsign;     
                                          return   -1;     
                                  &rightsign;     
                          &rightsign;     
                          finally       
                          &leftsign;     
                                  CloseHandle(hd);     
                          &rightsign;     
                  &rightsign;   
            
  以上代码来自     http://www.zpcity.com/ArLi//commonprj/cls_MinWorkSize.cs   
  
  依照知秋一叶的观点,系统采用这种方式来调整WorkingSet没有多大意义,但是看着taskmanager中的数字,确实不是很爽.

作者:fuyun 日期:2006-11-22
字体大小: 小 中 大

    系统为了加快程序的运行速度,给程序调用的资源做了缓存处理,以便下次再次使用同样的资源时提高响应速度。但是后台程序在启动以后并不需要立刻使用,为这些程序分配的缓存就没有必要。我们可以通过以下方法减少软件占用的内存。

    经过实际测试一个简单的程序,在Release方式编译后,启动占用8M左右的内存,而通过以下方法回收内存以后仅占用3M。很明显对于使用频率不高的程序该方法可以显著减少内存占用。

    public sealed class Program

&leftsign;

        [STAThread]

        static void Main()

        &leftsign;

            FlushMemory();

            Application.Run( );

        &rightsign;

 

        [DllImport("kernel32.dll")]

        private static extern bool SetProcessWorkingSetSize(

            IntPtr process,

            int minSize,

            int maxSize);

       

        private static void FlushMemory()

        &leftsign;

            GC.Collect();

            GC.WaitForPendingFinalizers();

            if(Environment.OSVersion.Platform == PlatformID.Win32NT)

                SetProcessWorkingSetSize( Process.GetCurrentProcess().Handle , -1, -1);

        &rightsign;

    &rightsign;

历史博文

标签:, , ,
十月 31, 2007 at 1:25 下午 by yippee 1,062 次
Category: Info
Tags: , , ,