我已经阅读了这个、这个、这个和这个以及其他十几个帖子/博客。
我在共享主机中有一个经常回收的 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 中附加的调试器运行它,以检查衍生线程中可能导致应用程序中止的未捕获异常。
我的问题是:
- 如何有效监控共享主机中的内存使用情况,以了解我的应用程序在应用程序回收之前消耗了多少?
- 为什么没有调用 global.asax 中的 Application_[End/OnEnd/Error] 处理程序?
- 我还能如何确定导致这些回收的原因?
谢谢。
编辑:基于@Jani Hyytiäinen 的回答
场景:线程#1 开始,然后是线程#2。线程 #1 达到内存限制但继续处理。线程#3 开始。线程 #1 完成,但 #2 在 #1 达到内存限制后处理超过 60 秒。
池然后不优雅地中止?#2 和 #3 会收到什么 http 响应(这些是 AJAX 调用,但我在 Fiddler 中收到 504 错误)?
#3 的请求是否被接受,还是只是排队等待新池启动?
有没有办法知道内存限制已经达到或即将达到?
欢迎任何策略。