gpt4 book ai didi

c# - 为什么我的代码显然在调用 LocalDataStoreMgr.GetNamedDataSlot?

转载 作者:太空狗 更新时间:2023-10-29 17:59:23 25 4
gpt4 key购买 nike

当我们的 ASP.NET 网站负载很重时,时不时地,其中一台服务器会疯狂使用 100% CPU 而根本没有响应。当我运行 stackdump.exe在运行过程中,我看到几乎所有线程都以 LocalDataStoreMgr.GetNamedDataSlot 方法结束。有些堆栈看起来好像我们自己的代码调用了 GetNamedDataSlot,其他堆栈显示 HttpApplication.ExecuteStepHttpWriter.Write 正在执行此操作。这是堆栈转储中的一个片段:

OS Thread Id:9232
System.LocalDataStoreMgr.GetNamedDataSlot(System.LocalDataStoreMgrN/A)
System.Web.HttpApplication.ExecuteStep(ASP.global_asaxSystem.Web.HttpApplication+AsyncEventExecutionStepSystem.Boolean&)
System.Web.HttpApplication+PipelineStepManager.ResumeSteps(System.Web.HttpApplication+PipelineStepManagerN/A)
System.Web.HttpApplication.BeginProcessRequestNotification(N/AN/AN/A)
System.Web.HttpRuntime.ProcessRequestNotificationPrivate(System.Web.HttpRuntimeSystem.Web.Hosting.IIS7WorkerRequestSystem.Web.HttpContext)
System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(N/ASystem.IntPtrN/AN/A)
System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(N/AN/AN/AN/A)
System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(N/AN/AN/AN/A)
System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(N/AN/AN/AN/A)

OS Thread Id:15308
System.LocalDataStoreMgr.GetNamedDataSlot(System.LocalDataStoreMgrN/A)
System.Web.HttpWriter.Write(System.Web.HttpWriterSystem.String)
System.Web.HttpWriter.Write(N/AN/A)
ASP.views_shared_advertcat_setadvertinformation_ascx.__Render__control1(N/AN/AN/A)
System.Web.UI.Control.RenderChildrenInternal(N/AN/AN/A)
System.Web.UI.Control.RenderControl(N/AN/AN/A)
System.Web.UI.Control.RenderControl(N/AN/AN/A)
System.Web.UI.Control.RenderChildrenInternal(N/AN/AN/A)
System.Web.Mvc.ViewPage.Render(System.Web.Mvc.ViewUserControl+ViewUserControlContainerPageN/A)
System.Web.UI.Control.RenderControl(N/AN/AN/A)
System.Web.UI.Control.RenderControl(N/AN/AN/A)
System.Web.UI.Page.ProcessRequestMain(System.Web.Mvc.ViewUserControl+ViewUserControlContainerPageSystem.BooleanSystem.Boolean)
System.Web.UI.Page.ProcessRequest(System.Web.Mvc.ViewUserControl+ViewUserControlContainerPageN/ASystem.Boolean)
System.Web.UI.Page.ProcessRequest(N/AN/AN/A)
System.Web.UI.Page.ProcessRequest(System.Web.Mvc.ViewUserControl+ViewUserControlContainerPage)
System.Web.UI.Page.ProcessRequest(N/AN/A)
System.Web.Mvc.ViewPage.ProcessRequest(N/AN/A)
System.Web.Mvc.ViewUserControl+ViewUserControlContainerPage.ProcessRequest(N/AN/A)
System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerWrapper+<>c__DisplayClass4.<Wrap>b__3(N/A)
System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerWrapper.Wrap(N/A)
System.Web.HttpServerUtility.ExecuteInternal(System.Web.HttpServerUtilitySystem.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerWrapperN/AN/AN/ASystem.Web.VirtualPathN/AN/ASystem.ExceptionSystem.String)
System.Web.HttpServerUtility.Execute(N/AN/AN/AN/AN/A)
System.Web.HttpServerUtility.Execute(N/AN/AN/AN/A)
System.Web.Mvc.ViewPage.RenderView(N/AN/A)
System.Web.Mvc.ViewUserControl.RenderView(N/AN/A)
System.Web.Mvc.ViewResultBase.ExecuteResult(N/AN/A)
System.Web.Mvc.ControllerActionInvoker+<>c__DisplayClass1a.<InvokeActionResultWithFilters>b__17(N/A)
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(Funda.Web.Mvc.Controllers.Shared.AdvertControllerSystem.Web.Mvc.ResultExecutingContextN/A)
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(N/AN/AN/AN/A)
System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass25.<BeginInvokeAction>b__22(System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass25N/A)
System.Web.Mvc.Controller+<>c__DisplayClass1d.<BeginExecuteCore>b__18(N/AN/A)
System.Web.Mvc.Async.AsyncResultWrapper+<>c__DisplayClass4.<MakeVoidDelegate>b__3(N/AN/A)
System.Web.Mvc.Controller.EndExecuteCore(Funda.Web.Mvc.Controllers.Shared.AdvertControllerN/A)
System.Web.Mvc.Async.AsyncResultWrapper+<>c__DisplayClass4.<MakeVoidDelegate>b__3(N/AN/A)
System.Web.Mvc.MvcHandler+<>c__DisplayClass8.<BeginProcessRequest>b__3(System.Web.Mvc.MvcHandler+<>c__DisplayClass8N/A)
System.Web.Mvc.Async.AsyncResultWrapper+<>c__DisplayClass4.<MakeVoidDelegate>b__3(N/AN/A)
System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerWrapper+<>c__DisplayClass4.<Wrap>b__3(N/A)
System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerWrapper.Wrap(N/A)
System.Web.HttpServerUtility.ExecuteInternal(System.Web.HttpServerUtilitySystem.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerAsyncWrapperN/AN/AN/ASystem.Web.VirtualPathN/AN/ASystem.ExceptionSystem.String)
System.Web.HttpServerUtility.Execute(N/AN/AN/AN/AN/A)
System.Web.HttpServerUtility.Execute(N/AN/AN/AN/A)
System.Web.Mvc.Html.ChildActionExtensions.ActionHelper(N/AN/AN/AN/AN/A)
ASP.views_homepage_homepage_aspx.__Render__control5(N/AN/AN/A)
System.Web.UI.Control.RenderChildrenInternal(N/AN/AN/A)
System.Web.UI.Control.RenderControl(N/AN/AN/A)
System.Web.UI.Control.RenderControl(N/AN/AN/A)
ASP.views_masterpages_homepage_master.__Render__control1(ASP.views_masterpages_homepage_masterSystem.Web.UI.HtmlTextWriterASP.views_masterpages_homepage_master)
System.Web.UI.Control.RenderChildrenInternal(N/AN/AN/A)
System.Web.UI.Control.RenderControl(N/AN/AN/A)
System.Web.UI.Control.RenderControl(N/AN/AN/A)
System.Web.UI.Control.RenderChildrenInternal(N/AN/AN/A)
System.Web.Mvc.ViewPage.Render(ASP.views_homepage_homepage_aspxN/A)
System.Web.UI.Control.RenderControl(N/AN/AN/A)
System.Web.UI.Control.RenderControl(N/AN/AN/A)
System.Web.UI.Page.ProcessRequestMain(ASP.views_homepage_homepage_aspxSystem.BooleanSystem.Boolean)
System.Web.UI.Page.ProcessRequest(ASP.views_homepage_homepage_aspxN/ASystem.Boolean)
System.Web.UI.Page.ProcessRequest(N/AN/AN/A)
System.Web.UI.Page.ProcessRequest(ASP.views_homepage_homepage_aspx)
System.Web.UI.Page.ProcessRequest(N/AN/A)
System.Web.Mvc.ViewPage.ProcessRequest(N/AN/A)
System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerWrapper+<>c__DisplayClass4.<Wrap>b__3(N/A)
System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerWrapper.Wrap(N/A)
System.Web.HttpServerUtility.ExecuteInternal(System.Web.HttpServerUtilitySystem.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerWrapperN/AN/AN/ASystem.Web.VirtualPathN/AN/ASystem.ExceptionSystem.String)
System.Web.HttpServerUtility.Execute(N/AN/AN/AN/AN/A)
System.Web.HttpServerUtility.Execute(N/AN/AN/AN/A)
System.Web.Mvc.ViewPage.RenderView(N/AN/A)
System.Web.Mvc.ViewResultBase.ExecuteResult(N/AN/A)
System.Web.Mvc.ControllerActionInvoker+<>c__DisplayClass1a.<InvokeActionResultWithFilters>b__17(N/A)
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(Funda.Web.Mvc.Attributes.DataForGoogleAnalyticsAttributeSystem.Web.Mvc.ResultExecutingContextN/A)
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(Funda.Web.Mvc.Attributes.SetLanguageFromProfileAttributeSystem.Web.Mvc.ResultExecutingContextN/A)
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(Funda.Web.Mvc.Attributes.DataForLoginAttributeSystem.Web.Mvc.ResultExecutingContextN/A)
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(Funda.Web.Mvc.Attributes.DataForNotifyAttributeSystem.Web.Mvc.ResultExecutingContextN/A)
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(Funda.Web.Mvc.Controllers.HomepageControllerSystem.Web.Mvc.ResultExecutingContextN/A)
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(N/AN/AN/AN/A)
System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass25.<BeginInvokeAction>b__22(System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass25N/A)
System.Web.Mvc.Controller+<>c__DisplayClass1d.<BeginExecuteCore>b__18(N/AN/A)
System.Web.Mvc.Async.AsyncResultWrapper+<>c__DisplayClass4.<MakeVoidDelegate>b__3(N/AN/A)
System.Web.Mvc.Controller.EndExecuteCore(Funda.Web.Mvc.Controllers.HomepageControllerN/A)
System.Web.Mvc.Async.AsyncResultWrapper+<>c__DisplayClass4.<MakeVoidDelegate>b__3(N/AN/A)
System.Web.Mvc.MvcHandler+<>c__DisplayClass8.<BeginProcessRequest>b__3(System.Web.Mvc.MvcHandler+<>c__DisplayClass8N/A)
System.Web.Mvc.Async.AsyncResultWrapper+<>c__DisplayClass4.<MakeVoidDelegate>b__3(N/AN/A)
System.Web.HttpApplication+CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute(N/A)
System.Web.HttpApplication+CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute(N/A)
System.Web.HttpApplication.ExecuteStep(ASP.global_asaxN/ASystem.Boolean&)
System.Web.HttpApplication.ExecuteStep(N/AN/AN/A)
System.Web.HttpApplication+PipelineStepManager.ResumeSteps(System.Web.HttpApplication+PipelineStepManagerN/A)
System.Web.HttpApplication.BeginProcessRequestNotification(N/AN/AN/A)
System.Web.HttpRuntime.ProcessRequestNotificationPrivate(System.Web.HttpRuntimeSystem.Web.Hosting.IIS7WorkerRequestSystem.Web.HttpContext)
System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(N/ASystem.IntPtrN/AN/A)
System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(N/AN/AN/AN/A)
System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(N/AN/AN/AN/A)
System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(N/AN/AN/AN/A)


OS Thread Id:25392
System.LocalDataStoreMgr.GetNamedDataSlot(System.LocalDataStoreMgrN/A)
Funda.App.Caching.CacheManager.GetFromCache(Funda.App.Caching.CacheManagerSystem.StringSystem.Func`1<Funda.Common.ServiceLayer.KoppelenEngineService.KlantMijnMakelaarKoppeling>)
Funda.Web.Mvc.Mappers.Shared.MijnMakelaarMapper.GetMijnMakelaarKoppeling(N/AN/A)
Funda.Web.Mvc.Mappers.SharedViewModelMapper.MapToLoginViewModel(N/AN/AN/AN/AN/AN/A)
Funda.Web.Mvc.Attributes.DataForLoginAttribute.OnActionExecuted(N/AN/A)
...

我想我明白什么是线程本地存储,但我不明白为什么这个调用显然是从这些地方发出的。我们不会在任何地方显式调用 Thread.GetNamedDataSlot。这些日志指示的方法中的 BCL 代码也没有(如果我可以信任 ILSpy)。

为什么这个方法被如此频繁地调用?我应该怎么做才能防止这种情况(对我来说就像一个锁定的热点)?


更新

GetFromCache 方法如下所示。 _instrumentation 字段是静态的。该类的实现确实涉及线程感知代码。

public T GetFromCache<T>(string key, Func<T> fetchAction, bool stampedeProtection, Func<T, Boolean> needsStoring)
{
// argh?
key = AddCacheVersionNumberToKey(key);

long startTime = 0;
long endTime = 0;
int timesSlept = 0;
if (_usingCounters)
{
NativeMethods.QueryPerformanceCounter(ref startTime);
}
_log.Debug("GetFromCache: [" + _durationGroup + "] " + key);

object obj = null;
while (obj == null)
{
obj = _store.Get(key);
if(obj is NotImplementedException)
{
// this is a nasty case where the store is not able to deserialize without knowing the type
obj = _store.Get<T>(key);
}
if (obj is NullValue)
{
return default(T);
}
if (CacheDisabledFromUrl(key) || obj is String && string.IsNullOrEmpty(obj.ToString()))
{
obj = null;
}
if (obj == null)
{
// Niet gevonden
if (timesSlept > Settings.Default.StampedeMaxSleepCycles)
{
_log.WarnFormat("Waiting for {0} x {1} ms for a locked cache key. Some other thread is taking very long to fill {2}. We will try it ourselves.", Settings.Default.StampedeMaxSleepCycles, Settings.Default.StampedeSleepTime, key);

stampedeProtection = false;
}
if (stampedeProtection)
{
// special case: we want to make sure that only one thread does the fetch after the miss.
if (_store.AcquireLock(key))
{
if (_usingCounters)
{
// log a miss only when we acquire the lock: other cases are just a slow hit
NativeMethods.QueryPerformanceCounter(ref endTime);
_instrumentation.RegisterMiss(_durationGroup, endTime - startTime, key);
startTime = endTime;
}

try
{
// We have to do the work
obj = fetchAction.Invoke();
if (_usingCounters)
{
NativeMethods.QueryPerformanceCounter(ref endTime);
_instrumentation.RegisterFetch(_durationGroup, obj, endTime - startTime, key);
}
if (obj == null)
{
_store.Store(key, new NullValue());

return default(T);
}
else if (needsStoring((T)obj))
{

if (_usingCounters)
{
NativeMethods.QueryPerformanceCounter(ref startTime);
}
_store.Store<T>(key, (T)obj);
if (_usingCounters)
{
NativeMethods.QueryPerformanceCounter(ref endTime);
_instrumentation.RegisterStore(_durationGroup, obj, endTime - startTime, key);
}
}
}
finally
{
_store.ReleaseLock(key);
}
}
else
{
// Wait and try again
// after 500 ms, hopefully, another thread will have filled the cache
Thread.Sleep(500);
timesSlept++;
}
}
else
{
// Standard flow for miss: fetch and store
if (_usingCounters)
{
// log a miss
NativeMethods.QueryPerformanceCounter(ref endTime);
_instrumentation.RegisterMiss(_durationGroup, endTime - startTime, key);
startTime = endTime;
}
obj = fetchAction.Invoke();
if (_usingCounters)
{
// log a fetch
NativeMethods.QueryPerformanceCounter(ref endTime);
_instrumentation.RegisterFetch(_durationGroup, obj, endTime - startTime, key);
}
if (obj == null)
{
_store.Store(key, new NullValue());

return default(T);
}
if (needsStoring((T)obj))
{
if (_usingCounters) NativeMethods.QueryPerformanceCounter(ref startTime);
_store.Store<T>(key, (T)obj);
if (_usingCounters)
{
NativeMethods.QueryPerformanceCounter(ref endTime);
_instrumentation.RegisterStore(_durationGroup, obj, endTime - startTime, key);
}
}
}
}
else
{
// Get is (uiteindelijk) gelukt. We loggen een Hit
if (_usingCounters)
{
NativeMethods.QueryPerformanceCounter(ref endTime);
_instrumentation.RegisterHit(_durationGroup, obj, endTime - startTime, key);
}

if (HttpContext.Current != null && HttpContext.Current.Request.Url.Query.Contains("queryinfo") && QueryTraceHttpContextAppender.Current != null)
{
string storeName = _store.GetType().Name.Replace("Store", "");
QueryTraceHttpContextAppender.Current.AppendDirect(String.Format("{0}: [Key] {1}", storeName, key));
}
}
}
return (T)obj;
}

更多extensive code snippet here .


结论

原来这奇怪的叫声确实是新遗物代理人引起的。案例中的方法都是检测方法。然而,在禁用 New Relic 的情况下,性能问题并没有消失。不过,堆栈提供的信息更多。所以问题回答了。 @jessehouwing,如果您将您的评论重新表述为答案,我很乐意接受。

最佳答案

我找到了这个解释

"线程使用本地存储内存机制来存储线程专有数据。公共(public)语言运行库在创建时为每个进程分配一个多槽数据存储数组。线程可以在数据存储中分配一个数据槽,在槽中存储和检索数据值,并在线程到期后释放槽以供重用。每个线程的数据槽都是唯一的。没有其他线程(甚至子线程)都无法获取该数据。

如果命名槽不存在,则分配一个新槽。命名数据槽是公开的,任何人都可以操纵。 "

来源是:http://msdn.microsoft.com/en-us/library/system.threading.thread.getnameddataslot%28v=vs.110%29.aspx

在本文中说明可以重写此行为

http://msdn.microsoft.com/en-us/library/6sby1byh%28v=vs.110%29.aspx

我认为问题是 .net 重复使用相同的名称来保存插槽,这会导致性能不佳。

可能比一种解决方案是清理运行时可调用包装器。

我发现了这个:

http://msdn.microsoft.com/en-us/library/system.threading.thread.disablecomobjecteagercleanup%28v=vs.100%29.aspx

关于c# - 为什么我的代码显然在调用 LocalDataStoreMgr.GetNamedDataSlot?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21158909/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com