到底是什么原因导致我的进程崩溃?
当你你有1000个w3wp.exe文件在eventviewer中意外停止,或者您的进程以某种奇怪的未定义方式退出,您不知道原因。
当一个进程崩溃或退出时,将触发一个称为EPR(Exit process)的特殊事件,因此使用类似于windbg.exe文件我们可以附加到进程中,等待epr被抛出,然后进行内存转储。安装windows调试工具时,会得到一个名为adplus的vbs脚本,它将为您自动执行此操作,并打印进程生命周期中发生的大多数异常的日志。
调试提示:当您在-crash模式下打开一个转储时,您将自动定位到崩溃发生时处于活动状态的线程(最有可能是可疑的线程)。如果您切换线程并想返回出错线程,请键入~列出所有线程,错误线程将被标记为一个点。
如果dump只显示进程中的一个活动线程,并且该线程是主线程,则该进程可能被外部的东西(运行状况监视、低系统内存、iisreset等)终止
不分先后顺序,以下是我们看到的支持率最高的一些:
Stack Overflow Exceptions
当为线程的堆栈分配的内存用完时,将发生堆栈溢出异常。默认情况下,它是1 MB,所以你的调用堆栈可能很深,所以大多数情况下发生这种情况是因为无限递归,也就是说,function调用FunctionB,后者再次调用FunctionB,后者再次调用FunctionB。。。没有停止条件。
不幸的是,异常处理应用程序块的错误使用是一个相当常见的模糊的无限递归情况。想象一下这个场景:你的应用程序得到一个异常,异常处理程序启动,你已经将它设置为记录到一个文件中。在记录日志时,您会得到某种类型的异常(比如访问被拒绝),并且您已经设置了异常处理程序来处理此异常。在这种情况下,您将在一个无限递归循环中处理一个异常,抛出另一个异常,处理它,抛出另一个。。。你明白要点了。这个故事的寓意是什么?不要在异常处理程序中使用异常处理程序来处理异常。
如果您运行“kb2000”(查看本机堆栈)和“!clrstack”(从sos.dll要查看托管堆栈),您可以找到递归模式以跟踪递归发生的位置/原因。
Out Of Memory Exceptions
大多数情况下,发生内存不足异常是由设计问题引起的,在设计问题中,缓存或会话作用域中存储的内存过多。如果以正确的方式使用缓存,那么缓存对于提高性能是非常有用的,也就是说,缓存的数据最多,而且缓存的时间不会超过需要的时间。在旧的ASP中,如果将对象存储在session范围内,就会出现问题,相信我,这是一种伪装,因为开发人员只在session范围内存储了最必要的项。例如,在会话范围内存储大型数据集通常会适得其反,因为您减少了网站可以处理的并发用户数,而且当内存足够大时,在缓存中进行垃圾收集和搜索所需的时间可能比从数据库中请求数据的开销要多真的需要它。
在何时应该在会话/缓存中存储内容以及何时不应该存储时,这里没有一刀切的解决方案。最好的做法是在早期阶段,确定应用程序需要能够处理的用户数,并在此基础上确定每个用户可以允许的存储量。然后对超过最大用户数的用户进行压力测试,以确保你能应付。最好是对处于会话状态的对象进行压力测试,看看性能如何。不同的用户数量不同。
在生产过程中,内存问题是很难解决的,因为它们通常需要大量的重新设计,所以在早期阶段花费一分钱可以节省很多钱。
调试提示:运行!dumpheap -type System.Web.Caching.Cache获取缓存根,然后对这些地址进行!do objsize,以了解您在缓存中为不同的应用程序存储了多少。(注意:InProc会话状态也存储在缓存中)
Unhandled exception in COM Component
- 上一篇: 仅通过转储来排除内存泄漏
- 下一篇: 使用Java中的InputStream读取文件数据