【问题标题】:If the Timer starts itself will the code that ran in past will ever be garbage collected?如果计时器自己启动,过去运行的代码是否会被垃圾收集?
【发布时间】:2019-04-04 02:33:00
【问题描述】:

我有一个基于 .net 的 Windows 服务,其中包含以下伪代码。它只是进入循环并根据条件立即执行 DoTask() 或在 60 秒后执行。这样做是为了防止在 DoTask() 已经运行时重叠的计时器调用。

我的问题是 - 如果这样做,已经在 DoTask() 中运行的代码/对象将被垃圾收集吗?或者,由于定时器是从定时器调用的 DoTask() 中启动的,所以内存堆栈会不断增加?

//called once when the service starts
function_startup
{
    mainTimer = new System.Timers.Timer();
    mainTimer.Interval = 10;
    mainTimer.Elapsed += OnTimedEvent;
    mainTimer.AutoReset = false;  // makes it fire only once
    mainTimer.Start();
}

private void OnTimedEvent(Object source, System.Timers.ElapsedEventArgs e)
{
    //some business logic goes here
    DoTask();
}

private void DoTask()
{
   //some business logic goes here
   //will the code that is here be garbage collected eventually 
   //or will always stay in memory stack increasing the memory that the service takes while running?

   //if condition a, run DoTask immediately again.
   if (condition_a)
   {
       mainTimer.Interval = 10;
       mainTimer.Start();
   }
   //else if condition b, sleep for a minute and then DoTask
   else (condition_b)
   {
       mainTimer.Interval = 60000; //run after 60 seconds
       mainTimer.Start();
   }
}

【问题讨论】:

    标签: c# timer windows-services


    【解决方案1】:

    您的代码中没有内存泄漏,也没有任何东西被收集或创建(根据您显示的内容)。

    1. 使用显示的代码,计时器 本身将永远不会被收集或重新创建。
    2. 如果您在DoTask() 范围内实例化类或结构,它们将在完成时超出范围,最终将被收集。

    【讨论】:

    • 谢谢。在处理小事情时,我的服务从 50,000k 内存开始。在处理新的重型材料后(实例化更大的类、处理等),它会上升到 300,000k。处理完成后,它似乎并没有倒退——我等了几个小时。有什么好的方法可以进一步解决这个问题?
    • @JohnWatt 使用内存分析器,但请注意,.Net 不会主动回收内存并将其返回给操作,除非它认为需要。这将是低效的
    猜你喜欢
    • 1970-01-01
    • 2021-05-25
    • 1970-01-01
    • 1970-01-01
    • 2013-08-10
    • 1970-01-01
    • 2011-05-06
    • 2012-05-31
    • 2011-10-05
    相关资源
    最近更新 更多