C#如何限制程序内存使用的大小

本文介绍如何利用C#中的SetProcessWorkingSetSize函数控制程序的内存使用,并探讨此方法的潜在弊端。
c#虽然内置垃圾回收机制,但是并不能解决程序占用内存庞大的问题,如果我们仔细观察任务管理器,我们会发现一个程序如果最小化的时候,它所占用的会骤然减小,这时操作系统会把程序用不到的内存暂时放到虚拟内存中,当我们再把程序最大化时,发现内存并没有完全的从虚拟内存调到内存中来,是因为操作系统的内存管理机制只调用目前需要的,那么剩下的,有可能将来调用,有可能根本没用。实现这个机理用到了一个API函数SetProcessWorkingSetSize (),c#中声明如下:
        [DllImport("kernel32.dll", EntryPoint = "SetProcessWorkingSetSize")]
        public static extern int SetProcessWorkingSetSize(int hProcess, int dwMinimumWorkingSetSize, int dwMaximumWorkingSetSize);
其中的参数内容:
hProcess:进程的句柄
dwMinimumWorkingSetSize:进程最小工作空间
dwMaximumWorkingSetSize:进程最大工作空间
          其中的hProcess,在c#中,如果限制当前编译的程序,用 GetCurrentProcess()来获得。
        但是这么做有一点要注意,在一个程序中不宜经常使用这个函数,比方说,我为了减少我的程序内存占用,把dwMinimumWorkingSetSize、dwMaximumWorkingSetSize的值都设置为最小,然后在设置一个timer,每隔一会就调用这个函数一次,这样看来程序占用内存时间少了,但是它带来一个很严重的弊端,操作系统为了实现限制内存的大小,会不断的进行内存与虚拟内存之间的转换,反而大大加重了操作系统的负担,所以不宜常用。
      大家可以运行一下周博通,然后看看任务管理器,用这个软件打开新浪网页,会发现任务管理器里面它的进程每5秒减少一次,而且是减少到最小,用的就是这个原理。
 
C#中,可以通过多种方式获取程序当前占用的内存大小。其中一种常见方法是使用 `System.Diagnostics` 命名空间中的 `Process` 类来获取当前进程的内存使用情况。以下是一些常用的内存指标和对应的实现方法: ### 获取当前进程的工作集内存(Working Set) 工作集内存是指进程当前使用的物理内存大小,包括共享内存部分。可以通过 `Process` 类的 `WorkingSet64` 属性获取。 ```csharp var process = Process.GetCurrentProcess(); long workingSetMemory = process.WorkingSet64; double memoryInMB = workingSetMemory / (1024.0 * 1024.0); Console.WriteLine($"当前进程的工作集内存为:{memoryInMB:F2} MB"); ``` ### 获取当前进程的私有内存(Private Bytes) 私有内存是指进程独占的内存大小,不包括共享内存部分。可以通过 `PerformanceCounter` 类查询 "Process" 类别的 "Private Bytes" 计数器来获取。 ```csharp var process = Process.GetCurrentProcess(); var privateMemoryCounter = new PerformanceCounter("Process", "Private Bytes", process.ProcessName); float privateMemoryUsage = privateMemoryCounter.NextValue(); double privateMemoryInMB = privateMemoryUsage / (1024 * 1024); Console.WriteLine($"当前进程的私有内存为:{privateMemoryInMB:F2} MB"); ``` ### 获取当前进程的虚拟内存(Virtual Bytes) 虚拟内存是指进程地址空间中已经使用到的内存总大小。可以通过 `Process` 类的 `VirtualMemorySize64` 属性获取。 ```csharp var process = Process.GetCurrentProcess(); long virtualMemorySize = process.VirtualMemorySize64; double virtualMemoryInMB = virtualMemorySize / (1024.0 * 1024.0); Console.WriteLine($"当前进程的虚拟内存为:{virtualMemoryInMB:F2} MB"); ``` ### 获取整个系统的内存使用情况 如果需要获取整个系统的内存使用情况,可以使用 `PerformanceCounter` 类查询 "Memory" 类别的 "% Committed Bytes In Use" 计数器。 ```csharp var ramCounter = new PerformanceCounter("Memory", "% Committed Bytes In Use"); float systemMemoryUsage = ramCounter.NextValue(); Console.WriteLine($"系统内存使用率为:{systemMemoryUsage:F2}%"); ``` ### 获取当前进程的线程数 可以通过 `Process` 类的 `Threads` 属性获取当前进程的线程数。 ```csharp var process = Process.GetCurrentProcess(); int threadCount = process.Threads.Count; Console.WriteLine($"当前进程的线程数为:{threadCount}"); ``` ### 注意事项 - 在使用 `PerformanceCounter` 时,需要确保应用程序有足够的权限访问性能计数器。 - 如果需要实时监控内存使用情况,可以在定时器中定期调用 `NextValue()` 方法获取最新的计数器值。 - 由于性能计数器的初始化可能需要一些时间,首次调用 `NextValue()` 时可能返回 0。可以通过调用 `NextValue()` 两次并间隔一定时间来解决此问题。 通过上述方法,可以灵活地监控和管理 C# 程序内存使用情况,从而优化程序性能并避免内存溢出问题[^4]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值