我不时地发现自己正在做一些适度的愚蠢的事情,导致我的程序分配了所有可以得到的内存,然后分配一些内存。
这种事情导致程序很快就会因为“内存不足”的错误而死亡,但是现在Windows将不再使用这种不存在的内存给应用程序,事实上显然已经准备好了这样做自杀。 当然不是,但是它将会使可用的物理RAM非常匮乏,即使运行任务pipe理器也需要半个小时的交换时间(所有失控的应用程序仍然在分配越来越多的内存)。
这不是经常发生,但是当它发生时是灾难性的。 我通常不得不重置我的机器,导致数据不时丢失,一般很多不便。
你有什么实际的build议,使这种错误的后果不那么可怕吗? 也许一些registry调整来限制一个应用程序被允许分配的最大数量的虚拟内存? 还是一些CLR的标志,将限制这只适用于当前的应用程序? (这通常是在.NET中,我自己这样做。)
( “不要耗尽内存”和“购买更多的内存”是没有用的 – 前者我无法控制,后者我已经完成了。)
每当运行有风险的应用程序时,您都可以保持打开命令提示符。 然后,如果它开始失控,则不必等待任务管理器加载,只需使用:
taskkill /F /FI "MEMUSAGE ge 2000000"
这将(理论上)强制杀死任何使用超过2GB的内存。
使用taskkill /?
获取所需选项的完整列表。
编辑:甚至更好,每隔几分钟运行命令作为计划的任务。 任何开始爆炸的进程都会自动启动。
您可以执行以下操作:限制流程的工作集大小。 将其粘贴到Main()方法中:
#if DEBUG Process.GetCurrentProcess().MaxWorkingSet = new IntPtr(256 * 1024 * 1024); #endif
这限制了您的进程可以声明的RAM数量,防止其他进程完全被换出。
其他事情你可以做:
特别是后面的维修任务对于旧机器是重要的。 碎片化的分页文件可能会极大地恶化交换行为。 常见的XP机器,从来没有被整理过,并有一个小的磁盘被允许填满。 页面文件碎片会导致大量的磁头寻道,严重影响另一个进程可以在合理的时间内将自己交换回RAM的几率。
显而易见的答案是在虚拟机内运行你的程序,直到经过测试,证明你确信这些事情不会发生。
如果您不喜欢这种开销,那么您可以在作业对象内部运行该进程,并在该作业对象的内存上设置一个限制。
在Windows中,您可以使用作业对象来控制进程的属性
在这种情况下,我通常使用任务管理器在机器运行内存之前终止进程。 即使机器开始分页非常糟糕,TaskMan仍然运行良好。 之后,机器通常会恢复。 Windows(比如7)的更新版本在这些情况下通常具有比早期版本更多的生存能力。 在没有DWM的情况下运行(关闭Vista和7中的Aero主题)通常也会让更多的时间来调用taskman进行监视,并有可能终止失控进程。