我已阅读 this , this , this和 this加上十几个其他帖子/博客。
我在共享主机中有一个经常回收的 ASP.Net 应用程序。我们使用 NLog 并在 global.asax 中有以下代码
void Application_Start(object sender, EventArgs e)
{
NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
logger.Debug("\r\n\r\nAPPLICATION STARTING\r\n\r\n");
}
protected void Application_OnEnd(Object sender, EventArgs e)
{
NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
logger.Debug("\r\n\r\nAPPLICATION_OnEnd\r\n\r\n");
}
void Application_End(object sender, EventArgs e)
{
HttpRuntime runtime = (HttpRuntime)typeof(System.Web.HttpRuntime).InvokeMember("_theRuntime", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.GetField, null, null, null);
if (runtime == null)
return;
string shutDownMessage = (string)runtime.GetType().InvokeMember("_shutDownMessage", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField, null, runtime, null);
string shutDownStack = (string)runtime.GetType().InvokeMember("_shutDownStack", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField, null, runtime, null);
ApplicationShutdownReason shutdownReason = System.Web.Hosting.HostingEnvironment.ShutdownReason;
NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
logger.Debug(String.Format("\r\n\r\nAPPLICATION END\r\n\r\n_shutDownReason = {2}\r\n\r\n _shutDownMessage = {0}\r\n\r\n_shutDownStack = {1}\r\n\r\n",
shutDownMessage, shutDownStack, shutdownReason));
}
void Application_Error(object sender, EventArgs e)
{
NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
logger.Debug("\r\n\r\nApplication_Error\r\n\r\n");
}
我们的日志文件中充斥着“APPLICATION STARTING”条目,但都没有
Application_OnEnd
, Application_End
,也不是 Application_Error
在这些自发重启期间被解雇。我知道他们正在工作,因为有用于接触 web.config 或/bin 文件的条目。我们还进行了内存过载测试,可以触发 OutOfMemoryException
被捕获在 Application_Error
.我们正在尝试确定虚拟内存限制是否导致回收。我们添加了
GC.GetTotalMemory(false)
在整个代码中,但这适用于 所有.Net ,不仅仅是我们的应用程序池,对吗?我们也试过var oPerfCounter = new PerformanceCounter();
oPerfCounter.CategoryName = "Process";
oPerfCounter.CounterName = "Virtual Bytes";
oPerfCounter.InstanceName = "iisExpress";
logger.Debug("Virtual Bytes: " + oPerfCounter.RawValue + " bytes");
但在共享主机中没有权限。
我在开发服务器上监视了应用程序,这些请求导致生产中的回收与附加的 ANTS Memory Profiler 相同,但似乎无法找到罪魁祸首。我们还使用 dev 中附加的调试器运行它,以检查可能导致应用程序中止的衍生线程中未捕获的异常。
我的问题是这些:
谢谢。
编辑:基于@Jani Hyytiäinen 的回答
设想:
线程#1 开始,然后是线程#2。线程 #1 达到内存限制但继续处理。线程#3 开始。线程 #1 完成,但 #2 在 #1 达到内存限制后处理超过 60 秒。
池然后不雅地中止? #2 和 #3 会收到什么 http 响应(这些是 AJAX 调用,但我在 Fiddler 中收到 504 错误)?
对 #3 的请求是否被接受,还是只是排队直到新池启动?
有没有办法知道内存限制已达到或即将达到?
欢迎任何策略。
最佳答案
iis 中有应用程序池关闭时间限制。假设它是 60 秒,并且在共享托管环境中存在应用程序池内存限制。您的应用程序池达到此限制,iis 告诉应用程序池完成当前请求的所有工作。如果所有请求在 60 秒之前完成处理,application_end 将触发,应用程序池将正常关闭。但是,如果 60 秒过去了并且请求仍在处理中,IIS 会感到不安并杀死应用程序池。这次没有 application_end 会触发。同样,不会触发任何错误事件处理程序。
关于asp.net - Application_End 是否应该触发自动应用程序池回收?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13388649/