GOLANG中time.After釋放的問題
在謝大群裡看到有同學在討論time.After
洩漏的問題,就算時間到了也不會釋放,瞬間就驚呆了,忍不住做了試驗,結果發現應該沒有這麼的恐怖的,是有洩漏的風險不過不算是洩漏,先看API的說明:
// After waits for the duration to elapse and then sends the current time
// on the returned channel.
// It is equivalent to NewTimer(d).C.
// The underlying Timer is not recovered by the garbage collector
// until the timer fires. If efficiency is a concern, use NewTimer
// instead and call Timer.Stop if the timer is no longer needed.
func After(d Duration) <-chan Time {
return NewTimer(d).C
}
提到了一句The underlying Timer is not recovered by the garbage collector
,這句挺嚇人不會被GC回收,不過後面還有條件until the timer fires
,說明fire
後是會被回收的,所謂fire
就是到時間了,寫個例子證明下壓壓驚:
package main
import "time"
func main() {
for {
<- time.After(10 * time.Nanosecond)
}
}
顯示記憶體穩定在5.3MB,CPU為161%,肯定被GC回收了的。當然如果放在goroutine也是沒有問題的,一樣會回收:
package main
import "time"
func main() {
for i := 0; i < 100; i++ {
go func(){
for {
<- time.After(10 * time.Nanosecond)
}
}()
}
time.Sleep(1 * time.Hour)
}
只是資源消耗會多一點,CPU為422%,記憶體佔用6.4MB。因此:
Remark: time.After(d)在d時間之後就會
fire
,然後被GC回收,不會造成資源洩漏的。
那麼API所說的If efficieny is a concern, user NewTimer instead and call Timer.Stop
是什麼意思呢?這是因為一般time.After
會在select中使用,如果另外的分支跑得更快,那麼timer是不會立馬釋放的(到期後才會釋放),比如這種:
select {
case time.After(3*time.Second):
return errTimeout
case packet := packetChannel:
// process packet.
}
如果packet非常多,那麼總是會走到下面的分支,上面的timer不會立刻釋放而是在3秒後才能釋放,和下面程式碼一樣:
package main
import "time"
func main() {
for {
select {
case <-time.After(3 * time.Second):
default:
}
}
}
這個時候,就相當於會堆積了3秒的timer沒有釋放而已,會不斷的新建和釋放timer,記憶體會穩定在2.8GB,這個當然就不是最好的了,可以主動釋放:
package main
import "time"
func main() {
for {
t := time.NewTimer(3*time.Second)
select {
case <- t.C:
default:
t.Stop()
}
}
}
這樣就不會佔用2.8GB記憶體了,只有5MB左右。因此,總結下這個After的說明:
- GC肯定會回收
time.After
的,就在d之後就回收。一般情況下讓系統自己回收就好了。 - 如果有效率問題,應該使用
Timer
在不需要時主動Stop。大部分時候都不用考慮這個問題的。
交作業。
相關文章
- Oracle中的Session kill不釋放問題OracleSession
- golang中的鎖競爭問題Golang
- 淺談C#託管程式中的資源釋放問題C#
- golang 釋放記憶體機制的探索Golang記憶體
- vector clear() 方法 記憶體釋放問題記憶體
- C/C++記憶體釋放應注意的問題C++記憶體
- Go坑:time.After可能導致的記憶體洩露問題分析Go記憶體洩露
- 【OpenCV】有關記憶體釋放的一些問題OpenCV記憶體
- 請教一個java程式記憶體釋放的問題Java記憶體
- 請教:JBoss伺服器不能釋放資源的問題伺服器
- 資料庫連線沒有釋放造成的奇怪問題資料庫
- 開放世界遊戲中的原路返回問題或直接傳送問題分析遊戲
- Hue的Impala模組沒有釋放連線的問題解決
- 刪除正在使用的檔案,空間不釋放的問題
- weblogic中釋出jive的問題Web
- 關於java執行緒釋放資源問題Java執行緒
- 關於如何釋放表空間的問題(About Reclaimable Unused Space)AI
- golang url解析問題Golang
- jdbc statment 資源釋放問題(高手請進入)JDBC
- Oracle delete資料後的釋放表空間問題的解決 --轉Oracledelete
- (轉載)刪除檔案後硬碟空間不釋放的問題硬碟
- golang中切片slice的引用問題Golang
- golang關鍵字select的三個例子, time.After模擬socket/心跳超時Golang
- golang 面試常考問題Golang面試
- golang中http server.go中的testHookServerServe函式變數寫法問題GolangHTTPServerHook函式變數
- 處理Linux刪除檔案後空間未釋放的問題Linux
- 賜教:關於JBoss伺服器無法釋放資源的問題伺服器
- 釋放檔案到臨時資料夾中所引發的安全問題
- Golang解決XORM的時區問題GolangORM
- golang websocket android連線的問題GolangWebAndroid
- Linux檔案刪除但空間不釋放問題篇Linux
- 深入解析 TiFlash丨多併發下執行緒建立、釋放的阻塞問題執行緒
- python 類變數 在多執行緒下的共享與釋放問題Python變數執行緒
- 記一次 Redisson 線上問題 → 你怎麼能釋放別人的鎖Redis
- golang json處理問題GolangJSON
- golang 開發環境問題Golang開發環境
- Golang GRPC 環境 問題GolangRPC
- 類的呼叫問題,對付大量程式碼中資料庫連線未及時釋放的程式碼維護問題資料庫