简体   繁体   English

System.Threading.Timer Windows服务内存泄漏

[英]System.Threading.Timer windows service memory leak

I have ac# console application running as a windows service. 我有一个作为Windows服务运行的ac#控制台应用程序。 The main thread of the application uses a System.Threading.Timer to manage 'sweeps' of a database. 应用程序的主线程使用System.Threading.Timer来管理数据库的“扫描”。 When the sweep starts on timer tick, the timer creates an object to find work in the database, and that object raises an event when work is found to spawn off the job into another thread. 当扫描在计时器滴答声中开始时,计时器将创建一个对象以在数据库中查找工作,并且当发现有将工作派生到另一个线程中的对象时,该对象将引发一个事件。

I appear to be suffering a memory leak, and my limited windbg abilities querying memory dumps has me thinking that the timer is not releasing something/itself to GC. 我似乎正在遭受内存泄漏,而我有限的查询内存转储的windbg能力使我认为计时器没有向GC释放某些东西。

windbg:

!dumpheap -type System.Object[]
...
02b01ae0 73a20cbc    32656   
02b09a80 73a20cbc     4112     
02b0e8e0 73a20cbc    16336     
02b5bf88 73a20cbc     1040     
02b5c3a8 73a20cbc     2064
10ee1010 73a20cbc 268435472     

Statistics:
      MT    Count    TotalSize Class Name
04210964        1           32 System.Func`2[[System.Type, mscorlib],[System.Func`2[[System.Object[], mscorlib],[Newtonsoft.Json.JsonConverter, Newtonsoft.Json]], mscorlib]]
7366a6a4        1           48 System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.Object[], mscorlib]]
04210a5c        1           48 System.Collections.Generic.Dictionary`2[[System.Type, mscorlib],[System.Func`2[[System.Object[], mscorlib],[Newtonsoft.Json.JsonConverter, Newtonsoft.Json]], mscorlib]]
73a20cbc     1194    268556916 System.Object[]
Total 1198 objects
0:000> !gcroot 10ee1010 
Thread 2dfc:
    04f1f70c 72db0687 System.Net.TimerThread.ThreadProc()
        ebp+50: 04f1f710 (interior)
            ->  02ac33a8 System.Object[]
            ->  072a5a38 System.Net.ServerCertValidationCallback
            ->  072a5a18 System.Net.Security.RemoteCertificateValidationCallback
            ->  10ee1010 System.Object[] 

Simplified and condensed code: 简化的代码:

TimeSpan timerInterval = TimeSpan.FromSeconds(5);
static Timer t;
public void startTimer()
{
    t = new System.Threading.Timer(TimerTick, null, TimeSpan.Zero, timerInterval);
}
public void TimerTick(Object TimerState)
{
    //run each query sweep synchronously
    t.Change(Timeout.Infinite, Timeout.Infinite);
    List<Query> queries = GetQueries();
    foreach (var query in queries)
    {
        var search = new QueryProcessor(query);
        //short term publisher?
        search.resultFoundEvent += QueryResultEventListener;
        search.RunSearch();
    }
    t.Change(timerInterval, timerInterval);
}
public void RunJob(JobDetails job)
{
    Task.Factory.StartNew(() => job.Execute(JobCallback));
}
//long term subscriber
public void QueryResultEventListener(object sender, FakeEventArgs e)
{
    RunJob(e.jobdetails);
}
public void JobCallback(JobDetails jobsuccess)
{
    //job was completed
}

As commented above, i don't think this is a traditional event handler leak, and windbg above has only this one massive entry at the bottom of !dumpheap -stat for System.Object[] . 如上所述,我认为这不是传统的事件处理程序泄漏,并且上面的windbg仅在System.Object[]!dumpheap -stat底部有一个大型条目。

Using jetBrains dotMemory I was able to determine that the handle open was from a line of code being called from referenced managed code down the stack in the job.Execute() . 使用jetBrains dotMemory,我可以确定打开的句柄是从job.Execute()堆栈中的引用托管代码调用的代码行中。 It was setting a delegate globally and causing ServerCertificateValidationCallback to pin a handle and never release. 这是在全局设置委托,并导致ServerCertificateValidationCallback固定句柄并且从不释放。

ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => { }; Feels like it behaves in the "short term publisher, long term subscriber" classic memory leak fashion, as the parent object of the constructor calling this line was disposed shortly after. 感觉就像它在“短期发布者,长期订阅者”经典内存泄漏方式中一样,因为构造函数的父对象调用此行不久之后就被处置了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM