今天這篇文章就和大家一起圍觀 gopark 的 27 個誘發原因。為了方便閱讀,我們會根據分類進行說明。
第一部分
標識 |
#意義 |
waitReasonZero |
|
#waitReasonGCAssistMarking |
GC assist marking |
waitReasonIOWait |
IO wait |
- waitReasonZero:無正式解釋,從使用情況來看。主要在 sleep 和 lock 的 2 個場景中使用。
- waitReasonGCAssistMarking:GC 輔助標記階段會讓阻塞等待。
- waitReasonIOWait:IO 阻塞等待時,例如:網路請求等。
第二部分
標識 |
#意義 |
waitReasonChanReceiveNilChan |
chan receive (nil chan) |
waitReasonChanSendNilChan |
|
#waitReasonChanSendNilChan
chan send (nil chan)#############
- waitReasonChanReceiveNilChan:對未初始化的 channel 進行讀取操作。
- waitReasonChanSendNilChan:對未初始化的 channel 進行寫入操作。
第三部分
標識 |
#意義 |
waitReasonDumpingHeap |
dumping heap |
waitReasonGarbageCollection |
garbage collection |
waitReasonGarbageCollectionScan |
#garbage collection scan |
##
- waitReasonDumpingHeap:對 Go Heap 堆 dump 時,這個的使用場景僅在 runtime.debug 時,也就是常見的 pprof 這一類採集時阻塞。
- waitReasonGarbageCollection:在垃圾回收時,主要場景是 GC 標記終止(GC Mark Termination)階段時觸發。
- waitReasonGarbageCollectionScan:在垃圾回收掃描時,主要場景是 GC 標記(GC Mark)掃描 Root 階段時觸發。
第四部分
標識 |
#意義 |
waitReasonPanicWait |
#panicwait |
waitReasonSelect |
select |
waitReasonSelectNoCases |
select (no cases) |
- waitReasonPanicWait:在 main goroutine 發生 panic 時,會觸發。
- waitReasonSelect:在呼叫關鍵字 select 時會觸發。
- waitReasonSelectNoCases:在呼叫關鍵字 select 時,若一個 case 都沒有,會直接觸發。
第五部分
標識 |
#意義 |
waitReasonGCAssistWait |
GC assist wait |
waitReasonGCSweepWait |
# GC sweep wait |
waitReasonGCScavengeWait |
GC scavenge wait |
- waitReasonGCAssistWait:GC 輔助標記階段中的結束行為,會觸發。
- waitReasonGCSweepWait:GC 清除階段中的結束行為,會觸發。
- waitReasonGCScavengeWait:GC scavenge 階段的結束行為,會觸發。 GC Scavenge 主要是新空間的垃圾回收,是一種經常運作、快速的 GC,負責從新空間中清理較小的物件。
第六部分
標識 |
#意義 |
waitReasonChanReceive |
chan receive |
waitReasonChanSend |
chan send |
waitReasonFinalizerWait |
#finalizer wait |
- waitReasonChanReceive:在 channel 進行讀取操作,會觸發。
- waitReasonChanSend:在 channel 進行寫入操作,會觸發。
- waitReasonFinalizerWait:在 finalizer 結束的階段,會被觸發。在 Go 程式中,可以透過呼叫
runtime.SetFinalizer
函數來為一個物件設定一個終結者函數。這個行為對應著結束階段造成的回收。
第七部分
標識 |
#意義 |
waitReasonForceGCIdle |
force gc (idle) |
waitReasonSemacquire |
semacquire |
waitReasonSleep |
#sleep |
- waitReasonForceGCIdle:強制 GC(空閒時間)結束時,會觸發。
- waitReasonSemacquire:當訊號量處理結束時,會觸發。
- waitReasonSleep:經典的 sleep 行為,會觸發。
第八部份
標識 |
#意義 |
waitReasonSyncCondWait |
sync.Cond.Wait |
waitReasonTimerGoroutineIdle |
|
#waitReasonTimerGoroutineIdle
|
#waitReasonTimerGoroutineIdle |
timer goroutine (idle)
######waitReasonTraceReaderBlocked######trace reader (blocked)#############
- waitReasonSyncCondWait:結合
sync.Cond
用法能知道,是在呼叫 sync.Wait
方法時所觸發。
- waitReasonTimerGoroutineIdle:與 Timer 相關,在沒有計時器需要執行任務時,會觸發。
- waitReasonTraceReaderBlocked:與 Trace 相關,ReadTrace會傳回二進位追蹤數據,將會阻塞直到資料可用。
第九部分
標識 |
#含義 |
waitReasonWaitForGCCycle |
wait for GC cycle |
waitReasonGCWorkerIdle |
|
#waitReasonGCWorkerIdle |
|
|
|
GC worker (idle)############waitReasonPreempted######preempted###########waitReasonDebugCall######debug call#######waitReasonDebugCall######debug call########waitReasonDebugCall######debug call### ##########
- waitReasonWaitForGCCycle:等待 GC 週期,會休眠造成阻塞。
- waitReasonGCWorkerIdle:GC Worker 空閒時,會休眠造成阻塞。
- waitReasonPreempted:發生循環呼叫搶佔時,會休眠等待調度。
- waitReasonDebugCall:呼叫 GODEBUG 時,會觸發。
總結
今天這篇文章是對開頭runtime.gopark 函數的詳解文章的一個補充,我們能夠對此了解到其誘發的因素。
主要場景為:
- #其他,例如:panic、finalizer、select 等。
我們可以根據這些特性,去拆解可能會造成阻塞的原因。其實也就沒必要記了,他們會導致阻塞肯定是由於存在影響控制流的因素,才會導致 gopark 的呼叫。
#