詞彙表/出問題的時候

殭屍程序

又稱:defunct程序、已失效的程序

簡短回答

殭屍程序是已經執行結束、卻仍在程序表中留有項目的程序,原因是它的父程序還沒有取得它的結束狀態。它不使用CPU,幾乎也不占用記憶體。

程序結束時,系統會保留一小筆記錄,讓父程序得知它是如何結束的。正常情況下,父程序會立刻讀取這筆記錄,項目隨之消失。如果父程序一直沒有讀取,已結束的程序就會以殭屍程序的形式留在列表中。

少量殭屍程序無害。數量持續增加,則代表父程式有錯誤。

如何在Mac上找出殭屍程序

在「終端機」中執行ps -axo pid,ppid,stat,comm | awk '$3 ~ /^Z/'。每一行都是一個殭屍程序,PPID欄會顯示該負責的父程序。

如何清除殭屍程序

殭屍程序無法被終止,因為它已經結束了。要處理的是父程序。結束或重新啟動父App後,殭屍程序就會交給launchd,由它清理。

不要為了清除殭屍程序而結束launchd或其他系統程序。如果父程序是系統程序,重新開機就能清除它們。

如何找到殭屍程序的父程序

在ps的完整指令欄中,殭屍程序會顯示為<defunct>,因為它的程式已經結束了。要處理的是它的父程序。

  1. 執行ps -axo pid,ppid,stat,comm | awk '$3 ~ /^Z/'列出殭屍程序。STAT欄中的Z表示殭屍程序。
  2. 記下PPID欄中的號碼。
  3. 執行ps -p <PPID> -o pid,user,command,查看父程序是哪個程式。
  4. 在活動監視器中,選擇「顯示方式」>「所有程序(依階層排列)」,可以看到同樣的父子程序樹狀結構。
  5. 處理父程序。如果它是你打開的App,就結束並重新打開它。如果它是「終端機」中的shell或工序指令,就關閉那個視窗或停止該工序指令。如果它是系統程序,就重新開機。

正常與值得擔心

父程式會透過wait系列的系統呼叫取得子程序的結束狀態。一個程式如果啟動了子程序卻從不等待它們,就會留下殭屍程序。這是父程式的錯誤,只有它的開發者能徹底修正。

短暫看到殭屍程序是正常的。它存在於程序結束到父程序讀取其結束狀態之間,這段時間通常很短。

如果同一個父程序一直留著很多殭屍程序,或它們的數量在幾個小時內不斷增加,就值得看一下。要計算數量,請執行ps -axo stat | grep -c '^Z'。要查看你Mac上的程序數量上限,請執行sysctl kern.maxproc kern.maxprocperuid。

殭屍程序、孤兒程序和當住的程序並不相同

這三個說法常被混為一談,而每一種需要不同的解決方法。

  • 殭屍程序已經執行結束,只剩下它在程序表中的項目。
  • 孤兒程序仍在執行,但它的父程序已經結束。macOS會把它交給launchd(PID 1),由launchd成為它新的父程序。
  • 當住的程序仍在執行,只是卡住了,在活動監視器中常顯示為「沒有回應」。和殭屍程序不同,它可以結束或強制結束。

不要做的事

少量殭屍程序無害,所以沒有必要為了清除它們而冒險。

  • 不要對殭屍程序的PID執行kill -9。它已經結束了,所以訊號不會有作用。
  • 不要為了清除殭屍程序而結束launchd或其他系統程序。重新開機能安全地達到同樣的效果。
  • 在弄清楚父程序是什麼之前,不要結束它。如果它是一個開著文件的App,請先儲存你的工作。

大家常問的問題

Mac上的殭屍程序是什麼?

它是已經結束、但因為父程序還沒取得它的結束狀態而仍被列出的程序。它不使用CPU。

如何終止殭屍程序?

沒辦法直接終止它。結束或重新啟動它的父程序(見ps輸出中的PPID欄),殭屍程序就會消失。

殭屍程序有害嗎?

少量無害。每個殭屍程序都會占用程序表中的一個位置,所以數量多且不斷增加時,最終可能造成問題,也代表父程式有錯誤。

為什麼kill -9無法移除殭屍程序?

殭屍程序並沒有在執行,所以訊號沒有東西可以停止。只有它的父程序取得它的結束狀態,或父程序結束,它才會消失。

重新開機能清除殭屍程序嗎?

可以。重新開機會結束所有程序,包括殭屍程序及其父程序。

殭屍程序是惡意軟體的跡象嗎?

不是。它們是Unix程序結束過程中的正常現象。同一個父程序留下很多殭屍程序,通常代表那個程式有錯誤。

相關詞條

逐步教學:Claude Code使用太多記憶體。

從Windows轉過來的嗎? 請參閱Mac版工作管理員,或最好用的活動監視器替代方案。也可以瀏覽詞彙表中的所有詞條。