内存占用应该不太好限制,网速可以通过腾讯电脑管家、360安全卫士或者火绒安全来限制。以火绒为例,在火绒的安全工具里打开流量监控,选择想限制网速的软件,填写想要限制多少网速就行。
一 SetProcessWorkingSetSize 的工作原理以下来自:
那么我的程序为什么能够将占用的内存移至虚拟内存呢?
其实,你也可以,试试看把一个程序最小化到任务栏,再看看任务管理器,看到没,你的程序占用的实际内存一下子减少 了,看来并不是我有什么方法能够压缩内存,而是 *** 作系统本身就有这个机制,即当程序不使用时(最小化), *** 作系统会调用某些命令,来将该程序占用的内存移 至虚拟内存,只保留一小部分常规代码
所以我们就看到了 这种情景,占用的内存一下子就缩小了。
那么:系统到底调用了什么指令呢?能不能在不缩小窗体的情况下来释放内存呢?
看看这个API SetProcessWorkingSetSize
这是从MSDN摘下的原话
Using the SetProcessWorkingSetSize function to set an application's minimum and maximum working set sizes does not guarantee that the requested memory will be reserved, or that it will remain resident at all times When the application is idle, or a low-memory situation causes a demand for memory, the operating system can reduce the application's working set An application can use the VirtualLock function to lock ranges of the application's virtual address space in memory; however, that can potentially degrade the performance of the system
使用这个函数来设置应用程序最小和最大的运行空间,只会保留需要的内存。当应用程序被闲置或系统内存太低时, *** 作系统会自动调用这个机制来设置应用程序的内存。应用程序也可以使用 VirtualLock 来锁住一定范围的内存不被系统释放。
When you increase the working set size of an application, you are taking away physical memory from the rest of the system This can degrade the performance of other applications and the system as a whole It can also lead to failures of operations that require physical memory to be present; for example, creating processes, threads, and kernel pool Thus, you must use the SetProcessWorkingSetSize function carefully You must always consider the performance of the whole system when you are designing an application
当你加大运行空间给应用程序,你能够得到的物理内存取决于系统,这会造成其他应用程序降低性能或系统总体降低性能,这也可能导致请求物理内存的 *** 作失败,例如:建立 进程,线程,内核池,就必须小心的使用该函数。
========================
事实上,使用该函数并不能提高什么性能,也不会真的节省内存。
因为他只是暂时的将应用程序占用的内存移至虚拟内存,一旦,应用程序被激活或者有 *** 作请求时,这些内存又会被重新占用。如果你强制使用该方法来 设置程序占用的内存,那么可能在一定程度上反而会降低系统性能,因为系统需要频繁的进行内存和硬盘间的页面交换。
BOOL SetProcessWorkingSetSize(
HANDLE hProcess,
SIZE_T dwMinimumWorkingSetSize,
SIZE_T dwMaximumWorkingSetSize
);
将 2个 SIZE_T 参数设置为 -1 ,即可以使进程使用的内存交换到虚拟内存,只保留一小部分代码
而桌面日历秀 之所以能够 总是保持 最小内存,是因为使用了定时器,不停的进行该 *** 作,,所以性能可想而知,虽然换来了小内存的假象,对系统来说确实灾难。
当然,该函数也并非无一是处,
1 。当我们的应用程序刚刚加载完成时,可以使用该 *** 作一次,来将加载过程不需要的代码放到虚拟内存,这样,程序加载完毕后,保持较大的可用内存。VB尤甚
2程序运行到一定时间后或程序将要被闲置时,可以使用该命令来交换占用的内存到虚拟内存。
最后,附上VB 调用的API 代码
Option Explicit
Private Declare Function SetProcessWorkingSetSize Lib "kernel32" (ByVal hProcess As Long, ByVal dwMinimumWorkingSetSize As Long, ByVal dwMaximumWorkingSetSize As Long) As Long
Private Declare Function GetCurrentProcess Lib "kernel32" () As Long
SetProcessWorkingSetSize GetCurrentProcess, -1, -1
将当前进程使用的内存归0,请放在适当的地方
二 区分物理内存、虚拟内存、Working Set(Memory)、Memory
以下来自:
这个问题在CSDN上碰到好几次,我每次都只给出了简单的答案:不要参考Task Manager的Mem Usage数据,那个数据的大小对程序性能没有直接影响。
下面是我分析这问题的一些思路,希望对对这个问题感兴趣的朋友有所帮助
Q: Is NET Alone
A: Nope! 前面Saucer说过了,这不是NET的问题,所有Windows程序都有类似的行为。例如下面的C程序:
void main { while(1); } //死循环,便于我们察看Task Manager
初次运行在我的机器上Mem Usage是632K,把Console最小化以后再恢复,Mem Usage变成了36K。显然,这不是一个NET独有的问题,而是Windows Memory Management的问题。那么和NET的GC机制也不会有太大的关系——虽然问题的表现形式很容易让人联想到GC。
Q: How much memory does my program use
A: 回答这个问题并不容易。先来看看 *** 作系统虚拟内存管理的一些基本概念:每个Windows进程都拥有4G的地址空间,但是你的机器显然没有4G的物理内 存。在多任务环境下,所有进程使用的内存总和可以超过计算机的物理内存。在特定的情况下,进程的一部分可能会从物理内存中删除而被暂存在硬盘的文件里 (pagefile),当进程试图访问这些被交换到pagefile里的内存的时候,系统会产生一个缺页中断(page fault),这时候Windows内存管理器会负责把对应的内存页重新从硬盘调入物理内存。
在某个时间内,一个进程可以直接访问到的物理内存(不发生缺页中断)叫做这个进程的Working Set;而一个进程从4G的地址空间当中实际分配(commit)了的、可访问的内存称为Committed Virtual Memory。Committed VM可能存在于Page File当中,WorkingSet则一定位于物理内存。
所以要回答上面的问题先要反问一句:What're you talking about Physical Memory or Committed Memory
Q: What is this "Mem Usage" data
A: From Task Manager Help: In Task Manager, the current Working Set of a process, in kilobytes
Mem Usage这个名字多少有些误导。它只表示这个进程当前占用的物理内存,也就是WorkingSet。WorkingSet不表示进程当前“占用”的所有 虚拟内存,该进程可能还有一部分数据被交换到pagefile当中。这些数据只有在被访问的时候才会被加载到物理内存。
Task Manager有另一列数据:VM Size,表示了一个进程分配的虚存(Committed Visual Memory)——实际的定义要比这个复杂一些,但这个定义对我们目前分析的问题已经足够了。以前面的C程序为例,在最小化前后的VM Size都是176K,并没有变化。
所以,结论很简单:当一个Windows程序被最小化的时候,Windows内存管理器把该进程的WorkingSet减到最小(根据先进先出FIFO或者最近最少使用LRU),把大部分数据交换到pagefile里。这很容易理解:我们通常总是希望为前台的应用程序留出更多物理内存,从而具有更好的性能。当该程序从最小化恢复的时候,Windows也不会完全加载程序的所有虚存,只是加载了必要的部分。这也很容易理解:程序启动阶段的代码通常在启动之后很少访问(对NET程序尤其如此,向fusion这样的模块在程序正常加载之后如果没有用到Reflection通常用不到)。
Q: So, Do we want a smaller workingset, or a larger one
A: It depends Conventional Wisdom tells us: The smaller, the better 但是在虚存的问题上却没这么简单。如果WorkingSet太小,程序运行过程中会产生很多缺页中断,这会严重影响程序的性能。另一方 面,WorkingSet太大会浪费“宝贵的”物理内存,降低整个系统的性能。 通常情况下(除非是对性能非常敏感的应用程序,并且你对Windows的内存管理了如指掌),建议不要在程序中自己调整WorkingSet的大小,而把 这个任务交给Windows内存管理器。调整的方法Saucer有提到: ();
Q: Final Question, Does my program really occupy that much physical memory
A: 这个问题看上去土了点——那个数字明明白白的写在Task Manager里面。
用 vadump检查的结果显示进程WorkingSet减小的主要原因是很多DLL在从最小化恢复的时候没有被加载到物理内存。我们知道DLL的一个特点是 代码共享,以NTDLLDLL为例,整个Windows系统的几乎所有应用程序(具体地说,Win32子系统的所有程序)都需要引用 NTDLLDLL,如果每人一份,光这个文件就的占用几十兆内存。Windows地解决办法是只在物理内存中保存一份NTDLLDLL的COPY,所 有引用这个DLL的程序都把这一份COPY映射到自己的内存空间里面,共享NTDLLDLL的代码段(每个进程的数据段仍然是独立的)。所以虽然 NTDLLDLL的大小被计算在你的程序的WorkingSet里面,但是从你的程序中去掉对这个DLL的引用并不会真的释放多少物理内存——你不用, 别人还在用呢!
所以,你的程序“独占”的物理内存远没有Mem Usage所表示的那么多,需要从Mem Usage里面扣除很多Shared Code Page (vadump里面可以看到)。
结论?不要参考Task Manager的Mem Usage数据,那个数据的大小对程序性能没有直接影响。用Perfomence Monitor里面与NET相关的Counter要容易、准确的多。
下面的shell脚本可以实时的监控系统中各个进程的CPU和内存的占用情况,用于限制进程CPU占用 率更加合理。
#!/bin/shPIDS=`top -bn 1 | grep "^ [1-9]" | awk ’{ if($9 > 50 || $10 > 25 && id -u $2 > 500) print $1}’`
for PID in $PIDS
do
renice +10 $PID
echo "renice +10 $PID"
done
能够将这个脚本放到cron中运行,比如每分钟检查一次,只需以root身份添加crontab项:
#crontab -e
limitsh
以后每个一分钟就会检查一次,调整占用50%以上CPU或25%内存的进程的nice值,从而使这样的进程优先级变低,被调度的机会减少,同时会向root发邮件提示该进程被调整过。
但是,限制内存使用最好还是用PAM,RedHat能够在/etc/security/limitsconf中配置。
栈内存可以在编译的时候指定参数来限定大小,一般2m差不多了
堆内存,可以重载new运算符或者重新定义new运算符,用于计算累加总的堆大小。当然,如果用得着的话。,malloc也得重载我不知道如何查看。但记得Linux(32位)中每个进程独享4GB的进程空间,需要注意的是这4G指的是虚拟内存,而非物理内存。可以查阅一下Linux虚拟内存机制相关资料。
要定制的话难度大啊!内核文件里用进程描述符(thread_info)表示一个进程,它是一个结构体,里面有个关于进程内存分配的字段(addr_limit)。具体自己研究研究吧!
如果只是对某个进程分配空间的话就简单多了。假如你要为当前进程设置2M的内存上限,可以通过current->addr_limit=2048实现。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)