TimerCallback.PerformTimerCallback 内存分配
我有一个 WCF 服务,我正在分析它的内存分配。
我看到每个请求上分配的内存的 36% 是通过 TimerCallBack.PerformTimerCallback 分配的,后者又调用以下内容:
ExecutionContext.CreateCopy
ExecutionContext.Run
所有这些分配甚至都不经过我的代码,只分配像 Hahtable.bucket 和 ExecutionContextRunData 这样的通用对象。
我在服务中出于应用原因使用计时器,我通过一个简单的回调为每个请求创建一个计时器,该回调更新布尔值,并在之后立即处理它。可能有关系吗?
这是相关的分配图:
<root> : 41 MB (100.00%)
System.Threading._TimerCallback::PerformTimerCallback static void (Object): 41 MB (100.00%)
System.Threading.ExecutionContext::CreateCopy System.Threading.ExecutionContext (): 30 MB (73.96%)
System.Threading.ExecutionContext::Run static void (System.Threading.ExecutionContext System.Threading.ContextCallback Object): 11 MB (26.04%)
System.Threading.ExecutionContext::RunInternal static void (System.Threading.ExecutionContext System.Threading.ContextCallback Object): 7.8 MB (19.18%)
System.Data.ProviderBase.DbConnectionFactory::PruneConnectionPoolGroups void (Object): 2.6 MB (6.42%)
System.Data.ProviderBase.DbConnectionPool::CleanupCallback void (Object): 183 kB (0.44%)
System.Data.ProviderBase.DbConnectionPoolGroup::ClearInternal bool (bool): 1.2 MB (3.06%)
System.Collections.Generic.Dictionary<T,U>::.ctor void (int32): 840 kB (2.02%)
System.Threading.ThreadPool::QueueUserWorkItem static bool (System.Threading.WaitCallback): 183 kB (0.44%)
System.Collections.Generic.Dictionary<T,U>::.ctor void (int32 <UNKNOWN>): 840 kB (2.02%)
System.Collections.Specialized.HybridDictionary::Add void (Object Object): 305 kB (0.73%)
System.Collections.Specialized.HybridDictionary::GetEnumerator void (): 255 kB (0.61%)
System.Collections.Specialized.ListDictionary::Add void (Object Object): 255 kB (0.61%)
System.Collections.Specialized.ListDictionary.NodeEnumerator::get_Current Object (): 204 kB (0.49%)
System.Threading.ThreadPool::QueueUserWorkItemHelper static bool (System.Threading.WaitCallback Object System.Threading.StackCrawlMark& bool): 183 kB (0.44%)
System.Collections.Generic.Dictionary<T,U>::Initialize void (int32): 840 kB (2.02%)
System.Threading._ThreadPoolWaitCallback::.ctor void (System.Threading.WaitCallback Object bool System.Threading.StackCrawlMark&): 135 kB (0.32%)
System.Threading.ExecutionContext::Capture static System.Threading.ExecutionContext (System.Threading.StackCrawlMark&): 135 kB (0.32%)
System.Runtime.Remoting.Messaging.LogicalCallContext::Clone Object (): 26 MB (63.75%)
System.Collections.Hashtable::.ctor void (int32 float32): 15 MB (36.34%)
System.Collections.Hashtable::GetEnumerator System.Collections.IDictionaryEnumerator (): 2.9 MB (7.07%)
System.Collections.Hashtable.bucket [] : 15 MB (36.34%)
System.Threading.ExecutionContext.ExecutionContextRunData : 7.8 MB (19.18%)
System.Collections.Hashtable : 4.5 MB (11.10%)
System.Threading.ExecutionContext : 4.3 MB (10.53%)
System.Runtime.Remoting.Messaging.LogicalCallContext : 3.8 MB (9.24%)
System.Collections.Hashtable.HashtableEnumerator : 2.9 MB (7.07%)
System.Collections.Generic.Dictionary<T,U>.Entry [] : 611 kB (1.47%)
System.Collections.Generic.Dictionary<T,U> : 560 kB (1.34%)
System.Collections.Specialized.ListDictionary : 305 kB (0.73%)
System.Collections.Specialized.ListDictionary.NodeEnumerator : 255 kB (0.61%)
System.Collections.Specialized.ListDictionary.DictionaryNode : 255 kB (0.61%)
System.Collections.Specialized.HybridDictionary : 255 kB (0.61%)
System.Int32 [] : 229 kB (0.55%)
System.Collections.DictionaryEntry : 204 kB (0.49%)
System.Threading._ThreadPoolWaitCallback : 48 kB (0.12%)
<bottom> : 41 MB (100.00%)
所有这些分配来自哪里?这正常吗?
有什么办法可以降低一些吗?
I have a WCF service and I'm profiling its memory allocation.
I see that 36% of the memory allocated on each request, is allocated through TimerCallBack.PerformTimerCallback, which in turn calls the following:
ExecutionContext.CreateCopy
ExecutionContext.Run
All these allocation don't even go through my code and only allocates generic objects like Hahtable.bucket and ExecutionContextRunData.
I'm using a Timer for applicative reasons in my service, I create one for every request with a simple callback that updates a boolean, and dispose it right after. Could it be related?
Here's the relevant allocation graph:
<root> : 41 MB (100.00%)
System.Threading._TimerCallback::PerformTimerCallback static void (Object): 41 MB (100.00%)
System.Threading.ExecutionContext::CreateCopy System.Threading.ExecutionContext (): 30 MB (73.96%)
System.Threading.ExecutionContext::Run static void (System.Threading.ExecutionContext System.Threading.ContextCallback Object): 11 MB (26.04%)
System.Threading.ExecutionContext::RunInternal static void (System.Threading.ExecutionContext System.Threading.ContextCallback Object): 7.8 MB (19.18%)
System.Data.ProviderBase.DbConnectionFactory::PruneConnectionPoolGroups void (Object): 2.6 MB (6.42%)
System.Data.ProviderBase.DbConnectionPool::CleanupCallback void (Object): 183 kB (0.44%)
System.Data.ProviderBase.DbConnectionPoolGroup::ClearInternal bool (bool): 1.2 MB (3.06%)
System.Collections.Generic.Dictionary<T,U>::.ctor void (int32): 840 kB (2.02%)
System.Threading.ThreadPool::QueueUserWorkItem static bool (System.Threading.WaitCallback): 183 kB (0.44%)
System.Collections.Generic.Dictionary<T,U>::.ctor void (int32 <UNKNOWN>): 840 kB (2.02%)
System.Collections.Specialized.HybridDictionary::Add void (Object Object): 305 kB (0.73%)
System.Collections.Specialized.HybridDictionary::GetEnumerator void (): 255 kB (0.61%)
System.Collections.Specialized.ListDictionary::Add void (Object Object): 255 kB (0.61%)
System.Collections.Specialized.ListDictionary.NodeEnumerator::get_Current Object (): 204 kB (0.49%)
System.Threading.ThreadPool::QueueUserWorkItemHelper static bool (System.Threading.WaitCallback Object System.Threading.StackCrawlMark& bool): 183 kB (0.44%)
System.Collections.Generic.Dictionary<T,U>::Initialize void (int32): 840 kB (2.02%)
System.Threading._ThreadPoolWaitCallback::.ctor void (System.Threading.WaitCallback Object bool System.Threading.StackCrawlMark&): 135 kB (0.32%)
System.Threading.ExecutionContext::Capture static System.Threading.ExecutionContext (System.Threading.StackCrawlMark&): 135 kB (0.32%)
System.Runtime.Remoting.Messaging.LogicalCallContext::Clone Object (): 26 MB (63.75%)
System.Collections.Hashtable::.ctor void (int32 float32): 15 MB (36.34%)
System.Collections.Hashtable::GetEnumerator System.Collections.IDictionaryEnumerator (): 2.9 MB (7.07%)
System.Collections.Hashtable.bucket [] : 15 MB (36.34%)
System.Threading.ExecutionContext.ExecutionContextRunData : 7.8 MB (19.18%)
System.Collections.Hashtable : 4.5 MB (11.10%)
System.Threading.ExecutionContext : 4.3 MB (10.53%)
System.Runtime.Remoting.Messaging.LogicalCallContext : 3.8 MB (9.24%)
System.Collections.Hashtable.HashtableEnumerator : 2.9 MB (7.07%)
System.Collections.Generic.Dictionary<T,U>.Entry [] : 611 kB (1.47%)
System.Collections.Generic.Dictionary<T,U> : 560 kB (1.34%)
System.Collections.Specialized.ListDictionary : 305 kB (0.73%)
System.Collections.Specialized.ListDictionary.NodeEnumerator : 255 kB (0.61%)
System.Collections.Specialized.ListDictionary.DictionaryNode : 255 kB (0.61%)
System.Collections.Specialized.HybridDictionary : 255 kB (0.61%)
System.Int32 [] : 229 kB (0.55%)
System.Collections.DictionaryEntry : 204 kB (0.49%)
System.Threading._ThreadPoolWaitCallback : 48 kB (0.12%)
<bottom> : 41 MB (100.00%)
Where do all these allocations come from? Is this normal?
Is there a way to lower some of it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
为了完整起见,问题是有人将 MaxBufferSize 和 MaxBufferPoolSize 值更改为之前值的 1,000 倍。
For completeness, problem was someone changed the MaxBufferSize and MaxBufferPoolSize values to a 1,000 times their previous values.