ASP.NET中的OutOfMemoryException(from kaneboy)

本文讨论了ASP.NET中OutOfMemoryException异常的原因及解决方法。通过调整memoryLimit参数来控制进程回收,确保服务器稳定运行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

来源:http://www.cnblogs.com/gxh973121/archive/2005/05/08/150607.html

在博客园看到了一位园友写的文章 《如何处理OutOfMemoryException异常?》 ,于是想和大家交流一下 ASP.NET 中出现 OutOfMemoryException 的问题。

实际上,在 ASP.NET Web 服务器上, ASP.NET 所能够用到的内存,通常不会等同于所有的内存数量。在 machine.config 配置文件中, <processModel>中有一个属性 “memoryLimit” ,这个属性的值是一个百分值,默认为 “60” ,即指定了 ASP.NET 进程(在任务管理器中大家就可以看到 ASP.NET 的进程, IIS5 中为 aspnet_wp IIS6 中为 w3wp )能够使用所有物理内存的 60% 。当 ASP.NET 使用的内存量超过这个限额时, IIS 会开始自动回收( recycle )进程,即创建一个新的进程去负责应付 Http 请求,而将旧进程所占用的内存回收。

当我们有一台很大内存的服务器时, “memoryLimit” 这个值是需要进行适当的调整的。比如我们准备了一台 4G 内存的服务器,那么 4G ×60% 2.4G 。但是,对于 Win32 操作系统,一个进程所能占用的所有内存空间只有 2G 。当 ASP.NET 进程占用的内存开始达到 2G 时,由于它并没有达到 2.4G 回收阈值 ,所以 IIS 不会启动 recycle 进程操作,但是由于 Win32 的限制,实际上已经不能给这个进程分配更多的内存了,于是, OutOfMemoryException 就很可能会被抛出了。为了避免这样的情况,我们就必须将 “memoryLimit” 适当调小,以让 IIS 更早的进行进程回收。

微软推荐的 ASP.NET 进程占用内存是不超过 60% ,并最好使计算出的实际值不超过 800M 。就是说,对于一台 4G 内存的服务器,最好将 “memoryLimit” 属性设置成 “20” 。设置一个适当的回收阈值,让 IIS 适时的进行进程回收,对于保证整个服务器的稳定运行,避免 OutOfMemoryException 是非常重要的。

IIS6 中, ASP.NET 进程的回收阈值不再由 配置节中的 “memoryLimit” 属性决定,而是由 IIS 管理器中的应用程序池配置中的设置决定。

但是,即使正确设置了这些配置,也不能保证完全避免 OutOfMemoryException 的发生,原因可能是多样而复杂的,比如内存回收操作可能耗时太多等等。开发人员要注意的,就是在代码中时刻牢记不要无谓的使用和浪费内存。 :)

如果你有一台大内存的服务器,同时对 Win32 操作系统中对于进程最高使用 2G 内存的限制很郁闷,可选的解决方法有两个:
1
、使用 /3GB 模式启动计算机,方法参加文后的链接
2
、使用 Windows Server 2003 64bits Edition

资源链接:
Microsoft IIS 5.0 Process Recycling Tool
,使 IIS5 具有类似 IIS6 的进程监视回收功能
Microsoft KB: Information on Application Use of 4GT RAM Tuning
Microsoft KB: 4 GB RAM 调试功能和物理地址扩展开关介绍

### FreeRTOS 中 vTaskSuspend 函数的用法 `vTaskSuspend()` 是 FreeRTOS 提供的一个任务管理函数,用于挂起指定的任务。一旦某个任务被挂起,它将不会被调度程序再次运行,直到通过 `vTaskResume()` 或其他恢复机制将其重新激活。 #### 函数原型 以下是 `vTaskSuspend()` 的函数原型定义: ```c void vTaskSuspend(TaskHandle_t xTaskToSuspend); ``` - **参数**: - `xTaskToSuspend`: 要挂起的任务句柄 (Task Handle)。如果传入 `NULL`,则表示当前正在执行的任务会被挂起[^1]。 #### 使用场景 该函数通常用于暂停某些低优先级或不必要立即运行的任务,从而释放 CPU 时间片给更高优先级的任务使用。需要注意的是,在调用此函数之前应确保目标任务确实可以安全地进入挂起状态。 #### 示例代码 下面是一个简单的例子展示如何利用 `vTaskSuspend()` 来控制两个不同功能的任务之间的切换: ```c #include "FreeRTOS.h" #include "task.h" // 定义全局变量存储第二个任务的手柄 TaskHandle_t xSecondTaskHandle = NULL; void vFirstTask(void *pvParameters){ while(1){ printf("This is the first task running.\n"); // 挂起自己让另一个任务有机会运行 vTaskSuspend(NULL); // 可能还有更多逻辑... } } void vSecondTask(void *pvParameters){ while(1){ printf("This is the second task running.\n"); // 让第一个任务继续工作前先延迟一段时间模拟实际操作耗时 vTaskDelay(pdMS_TO_TICKS(500)); // 主动唤醒第一个任务使其恢复正常运作流程 if(xSecondTaskHandle != NULL){ vTaskResume(xSecondTaskHandle); } // 自身也可以选择自我挂起到节省资源 vTaskSuspend(NULL); } } int main(){ // 创建并启动两个独立的任务实例 xTaskCreate(vFirstTask,"First Task",configMINIMAL_STACK_SIZE,NULL,tskIDLE_PRIORITY,&xSecondTaskHandle); xTaskCreate(vSecondTask,"Second Task",configMINIMAL_STACK_SIZE,NULL,(tskIDLE_PRIORITY + 1),NULL); // 启动调度器 vTaskStartScheduler(); return 0; } ``` 上述代码片段展示了基本的任务交互模式:当其中一个任务完成特定的工作周期后主动把自己挂起来以便于其它等待中的进程能够获得处理机会;而另一方则负责适时解除前者所处的状态限制使之得以重返活动队列当中去轮流占用计算单元来进行各自的运算过程。 #### 注意事项 - 如果尝试对已经处于挂起状态下的同一个对象重复应用本命令,则不会有额外效果发生。 - 当应用程序设计者决定不再需要某项服务的时候除了单纯停止它的动作之外还可以考虑彻底销毁之——这可以通过调用专门为此目的准备好的接口实现比如前面提到过的 `vTaskDelete()` 方法来达成最终清理的目的[^3]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值