C 定時器保活機制引起的記憶體洩露問題解決

2022-09-26 02:33:10 字數 2405 閱讀 1568

c# 中有三種定時器,system.windows.forms 中的定時器和 system.timers.timer 的工作方式是完全一樣的,所以,這裡我們僅討論 system.timers.timer 和 system.threading.timer

1、定時器保活

先來看乙個例子:

class program

static void start() }

public class foo

private void timer_elapsed(object sender, system.timers.elapsedeventargs e)

~foo()

}執行結果如下:

system.timers.timer elapsed.

system.timers.timer elapsed.

system.timers.timer elapsed.

system.timers.timer elapsed.

system.timers.timer elapsed.

system.timers.timer elapsed.

system.timers.timer elapsed.

...在 start 方法結束後,foo 例項已經失去了作用域,按理說應該被**,但實際並沒有(因為析構函式沒有執行,所以肯定例項未被**)。

這就是定時器的 保活機制,因為定時器需要執行 timer_elapsed 方法,而該方法屬於 foo 例項,所以 foo 例項被保活了。

但多數時候這並不是www.cppcns.com我們想要的結果,這種結果導致的結果就是 記憶體洩露,解決方案是:先將定時器 dispose。

public class foo : idisposable

}乙個很好的準則是:如果類中的任何欄位所賦的物件實現了idisposable 介面,那麼該類也應當實現 idisposable 介面。

在這個例子中,不止 dispose 方法,stop 方法和設定 autoreset = false,都能起到釋放物件的目的。但是如果在 stop 方法之後又呼叫了 start 方法,那麼物件依然會被保活,即便 stop 之後進行強制垃圾**,也無法**物件。

system.timers.timer和system.threading.timer的保活機制是類似的。

保活機制是由於定時器引用了例項中的方法,那麼,如果定時器不引用例項中的方法呢?

2、不保活下 system.timers.timer 和 system.threading.timer 的差異

要消除定時器對例項方法的引用也很簡單,將 timer_elapsed 方法改成 靜態 的就好了。(靜態方法屬於類而非例項。)

改成靜態方法後再次執行示例,結果如下:

system.timers.timer elapsed.

system.timers.timer elapsed.

system.timers.timer elapsed.

system.timers.timer elapsed.

---------- end ----------

system.timers.timer elapsed.

system.timers.timer elapsed.

system.timers.timer elapsed.

...foo 例項是被銷毀了(析構函式已執行,列印出了 end),但定時器還在執行,這是為什麼呢?

這是因為,.net framework 會確保 system.timers.timer 的存活,即便其所屬例項已經被銷毀**。

如果改成 system.threading.timer,又會如何?

class program

static void start() }

public class foo2

static void timertick(object state)

~foo2()

}注意,這裡的 timertick 方法是靜態的。執行結果如下:

system.threading.timer elapsed.

system.threading.timer elapsed.

system.threading.timer elapsed.

system.threading.timer elapsed.

system.threading.timer elapsed.

---------- end ----------

可見,隨著 foo2 例項銷毀,_sshywhtimer 也自動停止並銷毀了。

這是因為,.net framework 不會儲存啟用 system.threading.timer 的引用,而是直接引用**委託。

本文標題: c# 定時器保活機制引起的記憶體洩露問題解決

本文位址: /ruanjian/csharp/300276.html

C 定時器保活機制引起的記憶體洩露問題

c 中有三種定時器,system.windows.forms中的定時器和system.timers.timer的工作方式是完全一樣的,所以,這裡我們僅討論system.timers.timer和system.threading.timer 先來看乙個例子 class program static v...

TCP保活定時器

tcp有keepalive功能,它和http的keepalive功能目的不一樣。tcp伺服器希望知道客戶端是否崩潰 重新啟動或者中間路由不通。保活定時器就提供這種功能。在進一步介紹tcp的保活定時器前,先了解乙個概念 長連線和短連線。tcp是長連線 長連線 建立乙個連線,多個請求復用這個連線,最後再...

(23)TCP的保活定時器

一 簡介 對於運輸層是否應該存在保活定時器的討論一直都有,一些專家覺得這應該有應用層自行維護。如果乙個給定的連線在2小時內沒有任何動作,那麼伺服器就向客戶傳送乙個探查報文段。客戶主機必須處於以下4個狀態之一。1 客戶主機依然正常執行,並從伺服器可達。客戶的tcp響應正常,而伺服器也知道對方的正常工作...