最近看到的一個問題,Java線程切換為什么成本會高,由於Java線程的切換是需要用戶態和內核態轉換的,在學習計算機操作系統時,狀態轉換成本高就被當做常識,那么為什么會成本高,記錄在這方便復習
(此外,java程序的加鎖和解鎖也涉及到狀態轉換)
應用程序的執行必須依托於內核提供的資源,包括CPU資源、存儲資源、I/O資源等。為了使上層應用能夠訪問到這些資源,內核必須為上層應用提供訪問的接口:即系統調用。因此,如果一個程序需要從用戶態進入內核態,那么它必須執行系統調用語句。
當程序中有系統調用語句,程序執行到系統調用時,首先使用類似int 80H的軟中斷指令,保存現場,去系統調用,在內核態執行,然后恢復現場,每個進程都會有兩個棧,一個內核態棧和一個用戶態棧。當int中斷執行時就會由用戶態棧轉向內核態棧。系統調用時需要進行棧的切換。而且內核代碼對用戶不信任,需要進行額外的檢查。系統調用的返回過程有很多額外工作,比如檢查是否需要調度等。
系統調用一般都需要保存用戶程序得上下文(context), 在進入內核的時候需要保存用戶態的寄存器,在內核態返回用戶態的時候會恢復這些寄存器的內容。這是一個開銷的地方。 如果需要在不同用戶程序間切換的話,那么還要更新cr3寄存器,這樣會更換每個程序的虛擬內存到物理內存映射表的地址,也是一個比較高負擔的操作