亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

操作系統(tǒng)的內(nèi)核態(tài)和用戶態(tài)場景詳解

 更新時間:2025年06月30日 09:17:10   作者:找不到、了  
這篇文章主要介紹了操作系統(tǒng)的內(nèi)核態(tài)和用戶態(tài)場景,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

日常開發(fā)中,不知道有沒有思考過這樣的問題?

為什么Java的new Thread().start()只需幾微秒,而Linux的fork()進程卻要毫秒級?"

"為何Redis單線程卻能支持10萬QPS,而你的Java多線程程序卡在8千?"

或者如下圖所示:

| 操作                | 耗時        | 狀態(tài)切換次數(shù) |
|---------------------|-------------|--------------|
| Java方法調(diào)用        | 3 ns        | 0            |
| 系統(tǒng)調(diào)用(read)      | 100 ns      | 2            |
| 線程上下文切換      | 1 μs        | 2+           |
| 進程創(chuàng)建(fork)      | 1 ms        | 10+          |

Java 方法調(diào)用為什么快?(3 ns)

純用戶態(tài)操作

  • JVM 直接在用戶空間執(zhí)行方法調(diào)用,無需切換CPU特權(quán)級(無內(nèi)核介入)。

直接跳轉(zhuǎn)

  • 通過棧幀方法表直接跳轉(zhuǎn),現(xiàn)代JVM還會用JIT編譯優(yōu)化(內(nèi)聯(lián)等)。

硬件加速

  • CPU 的流水線、分支預(yù)測等機制可以高效處理這種簡單跳轉(zhuǎn)。

而對于read方法為什么這么慢?可參考如下:

接下來就隨著這篇文章來深入了解程序運行在操作系統(tǒng)里面的原理。

用戶態(tài)和內(nèi)核態(tài)是操作系統(tǒng)的兩種運行狀態(tài),用于保護系統(tǒng)資源和確保安全。程序通過系統(tǒng)調(diào)用、異常中斷從用戶態(tài)進入內(nèi)核態(tài)。

系統(tǒng)調(diào)用是進程主動請求操作系統(tǒng)服務(wù)的方式,涉及CPU上下文切換,包括用戶棧到內(nèi)核棧的切換,并在完成后返回用戶態(tài)。

下面將從硬件實現(xiàn)、操作系統(tǒng)原理及JVM設(shè)計三個層次進行深度剖析。

1、硬件層

分為特權(quán)級與保護機制,關(guān)于硬件這部分可以進行簡單的了解。

1.1、CPU特權(quán)級(Ring Model)

如下圖所示:

現(xiàn)代CPU通常采用多級特權(quán)環(huán)(x86架構(gòu)為Ring 0~Ring 3):

  • Ring 0(內(nèi)核態(tài)):執(zhí)行所有指令(如LGDT加載全局描述符表、HLT停機指令)
  • Ring 3(用戶態(tài)):受限指令會觸發(fā)General Protection Fault(GPF)異常
  • 特權(quán)級切換:通過syscall/sysenter(快速系統(tǒng)調(diào)用指令)或中斷門實現(xiàn)

關(guān)鍵點:硬件強制隔離用戶態(tài)與內(nèi)核態(tài),任何越權(quán)操作都會觸發(fā)CPU異常。

1.2、內(nèi)存保護:MMU與頁表

  • 用戶態(tài)進程:只能訪問虛擬地址空間中用戶區(qū)(如Linux的0x00000000~0x7fffffff
  • 內(nèi)核態(tài):可訪問全部地址空間(包括內(nèi)核區(qū)0xc0000000以上)
  • 頁表權(quán)限位:通過PTE(Page Table Entry)的U/S位(User/Supervisor)控制訪問權(quán)限

稍微擴展下:

U/S位(bit 2):控制訪問權(quán)限

  • 1:用戶態(tài)可訪問
  • 0:僅內(nèi)核態(tài)可訪問
示例:Linux進程地址空間布局
用戶態(tài)可訪問:
  0x00000000-0x7fffffff ┌───────────────┐
                        │    用戶空間    │
內(nèi)核態(tài)獨占:
  0xc0000000-0xffffffff ┌───────────────┐
                        │    內(nèi)核空間    │

1.3、調(diào)用流程

當(dāng)執(zhí)行open()系統(tǒng)調(diào)用時:

  • CPU從用戶態(tài)(Ring 3)進入內(nèi)核態(tài)(Ring 0)
  • MMU臨時忽略U/S位檢查
  • 內(nèi)核訪問struct file等數(shù)據(jù)結(jié)構(gòu)(位于內(nèi)核內(nèi)存區(qū)域)
  • 返回用戶態(tài)時重新啟用U/S位保護

如用戶態(tài)代碼訪問內(nèi)核態(tài)內(nèi)存的時候:

// 用戶態(tài)嘗試讀取內(nèi)核地址會導(dǎo)致段錯誤
void *kernel_addr = (void *)0xffff888000000000;
printf("%d", *(int *)kernel_addr); // 觸發(fā)#PF(Page Fault)異常
  • CPU檢測到U/S=0的頁在用戶態(tài)被訪問
  • 觸發(fā)Page Fault(錯誤碼0x00000005:用戶態(tài)+讀操作)
  • 內(nèi)核發(fā)送sigsegv信號終止進程

小結(jié)

從硬件特權(quán)級到JVM的巧妙封裝,每一層設(shè)計都在平衡安全與效率?,F(xiàn)代Java生態(tài)(如GraalVM、Project Loom)正在進一步模糊這一界限,但底層原理仍是性能優(yōu)化的核心知識。

2、操作系統(tǒng)狀態(tài)

2.1、分類

如下圖所示:

用戶態(tài)和內(nèi)核態(tài)是操作系統(tǒng)的兩種運行狀態(tài)。

內(nèi)核態(tài):

定義:操作系統(tǒng)內(nèi)核運行的特權(quán)模式。

特點

  • 可以執(zhí)行所有CPU指令
  • 可以訪問全部內(nèi)存空間
  • 可以直接操作硬件設(shè)備
  • 權(quán)限最高,但風(fēng)險也大

處于內(nèi)核態(tài)的 CPU 可以訪問任意的數(shù)據(jù),包括外圍設(shè)備,比如網(wǎng)卡、硬盤等,處于內(nèi)核態(tài)的 CPU 可以從一個程序切換到另外一個程序,并且占用 CPU 不會發(fā)生搶占情況,一般處于特權(quán)級 0 的狀態(tài)我們稱之為內(nèi)核態(tài)。

用戶態(tài):

定義:應(yīng)用程序運行的普通權(quán)限模式。

特點

  • 只能訪問受限的CPU指令集和內(nèi)存空間
  • 不能直接訪問硬件設(shè)備
  • 執(zhí)行特權(quán)指令會導(dǎo)致異常
  • 安全性高,一個進程崩潰不會影響整個系統(tǒng)

處于用戶態(tài)的 CPU 只能訪問受限資源,不能直接訪問內(nèi)存等硬件設(shè)備,不能直接訪問內(nèi)存等硬件設(shè)備,必須通過「系統(tǒng)調(diào)用」陷入到內(nèi)核中,才能訪問這些特權(quán)資源。

2.2、切換方式

如下圖所示:

分為系統(tǒng)調(diào)用、中斷和異常三種切換方式。

2.3、系統(tǒng)調(diào)用

系統(tǒng)調(diào)用實際上是一個軟件中斷,它將執(zhí)行的上下文從用戶模式切換到內(nèi)核模式。操作系統(tǒng)內(nèi)核作為更高的特權(quán)級別,可以訪問保護的內(nèi)存區(qū)域和硬件資源。這是一個非常重要的安全機制,因為它阻止了用戶程序直接訪問硬件和敏感信息。

以下是一些常見的系統(tǒng)調(diào)用:

1、文件操作:

  • open():打開或創(chuàng)建文件
  • read():讀取文件內(nèi)容
  • write():寫入文件內(nèi)容
  • close():關(guān)閉打開的文件
  • lseek():移動文件的讀/寫指針

2、進程管理:

  • fork():創(chuàng)建新的子進程
  • exit():結(jié)束進程
  • wait():暫停父進程,直到子進程結(jié)束
  • exec():在當(dāng)前進程上下文中執(zhí)行新的程序

3、內(nèi)存管理:

  • brk()、sbrk():改變數(shù)據(jù)段的大小
  • mmap():創(chuàng)建一個新的映射區(qū)域
  • munmap():刪除一個映射區(qū)域

4、設(shè)備管理:

  • ioctl():對設(shè)備進行控制
  • fcntl():執(zhí)行各種文件操作

5、通信:

  • socket():創(chuàng)建一個新的套接字
  • bind():將套接字綁定到地址
  • listen()、accept():在套接字上監(jiān)聽連接
  • connect():發(fā)起到另一套接字的連接
  • send()、recv():發(fā)送/接收數(shù)據(jù)
  • shutdown():關(guān)閉套接字的部分功能

當(dāng)程序發(fā)出系統(tǒng)調(diào)用時,它會提供一個系統(tǒng)調(diào)用的編號和一組參數(shù)來指定操作系統(tǒng)需要執(zhí)行的具體任務(wù)。然后,CPU會將執(zhí)行上下文切換到內(nèi)核模式,并開始執(zhí)行與編號對應(yīng)的系統(tǒng)調(diào)用。

當(dāng)發(fā)出系統(tǒng)調(diào)用的時候,如下圖所示:

3、在Java領(lǐng)域的體現(xiàn)

操作系統(tǒng)內(nèi)核態(tài)與用戶態(tài)的劃分是計算機系統(tǒng)安全的基石,而Java作為運行在用戶態(tài)的高級語言,其與操作系統(tǒng)的交互涉及復(fù)雜的底層機制。

3.1. JVM與操作系統(tǒng)的交互

如下圖所示:

JVM本身:大部分運行在用戶態(tài),但會通過系統(tǒng)調(diào)用與內(nèi)核交互

系統(tǒng)調(diào)用示例

  • 文件I/O操作(java.io包)
  • 網(wǎng)絡(luò)通信(java.net包)
  • 線程管理(java.lang.Thread)

3.2. Java Native Interface (JNI)

  • 本地方法:通過JNI調(diào)用的本地代碼可能涉及內(nèi)核態(tài)操作
  • 風(fēng)險:錯誤的本地代碼可能導(dǎo)致系統(tǒng)不穩(wěn)定

3.3. 內(nèi)存管理

  • Java堆內(nèi)存:在用戶態(tài)由JVM管理
  • 直接內(nèi)存(NIO):ByteBuffer.allocateDireact()可能涉及內(nèi)核態(tài)的內(nèi)存分配

3.4. 多線程實現(xiàn)

  • Java線程:通常映射到操作系統(tǒng)原生線程(1:1模型)
  • 線程調(diào)度:最終由操作系統(tǒng)內(nèi)核調(diào)度器在內(nèi)核態(tài)完成

3.5. 性能考量

系統(tǒng)調(diào)用開銷:頻繁的I/O操作會導(dǎo)致用戶態(tài)/內(nèi)核態(tài)切換,影響性能

優(yōu)化技術(shù)

  • 緩沖技術(shù)(如BufferedInputStream)
  • 批量操作(如NIO的Selector)
  • 零拷貝技術(shù)(FileChannel.transferTo)

4、系統(tǒng)調(diào)用

系統(tǒng)調(diào)用與進程管理,如下圖所示:

更詳細的調(diào)用可參考:

4.1. 系統(tǒng)調(diào)用(Syscall)

以Linux的read()系統(tǒng)調(diào)用為例:

  • 用戶態(tài)觸發(fā):調(diào)用libc的read()函數(shù)
  • 軟中斷:libc通過int 0x80(傳統(tǒng))或Syscall指令(x86-64)陷入內(nèi)核
  • 查表跳轉(zhuǎn):CPU根據(jù)中斷描述符表(IDT)找到系統(tǒng)調(diào)用處理程序
  • 內(nèi)核執(zhí)行:切換到內(nèi)核棧,執(zhí)行sys_read()函數(shù)
  • 返回用戶態(tài):通過iret指令恢復(fù)用戶態(tài)上下文

性能開銷:一次系統(tǒng)調(diào)用約需100~300ns,主要消耗在寄存器保存/恢復(fù)和緩存失效(TLB flush)。

1、用戶態(tài)與內(nèi)核態(tài)的緩存區(qū)

如下所示:

1.用戶態(tài)緩存區(qū)

來源

用戶程序(如 C/C++ 的stdio緩沖、Java 的BufferedReader)會維護自己的用戶空間緩沖區(qū)。

作用

減少系統(tǒng)調(diào)用次數(shù),提高性能。例如:用戶程序調(diào)用fwrite()時,數(shù)據(jù)先寫入用戶緩沖區(qū),達到一定大小后才觸發(fā)系統(tǒng)調(diào)用(write())。若用戶緩沖區(qū)未命中(無數(shù)據(jù)),才會進入內(nèi)核態(tài)。

2.內(nèi)核態(tài)緩存區(qū)

來源

操作系統(tǒng)內(nèi)核維護頁緩存(Page Cache)和網(wǎng)絡(luò)棧緩沖區(qū)。

作用

  • 頁緩存:緩存磁盤文件的數(shù)據(jù),減少磁盤IO。
  • 網(wǎng)絡(luò)棧緩沖區(qū):緩存網(wǎng)絡(luò)數(shù)據(jù)包(如 TCP 的send buffer和recv buffer)。

2、調(diào)用的流程

觸發(fā)方式:用戶程序通過read()/write()等系統(tǒng)調(diào)用進入內(nèi)核態(tài)。

流程

1、檢查用戶緩沖區(qū)

若用戶程序的緩沖區(qū)有數(shù)據(jù),直接返回(無需進入內(nèi)核)。

2、進入內(nèi)核態(tài)

若用戶緩沖區(qū)無數(shù)據(jù),觸發(fā)系統(tǒng)調(diào)用(如read()),進入內(nèi)核態(tài)。

3、內(nèi)核處理請求

檢查內(nèi)核緩存(Page Cache):若有數(shù)據(jù),直接返回給用戶態(tài)。若無數(shù)據(jù):發(fā)起物理IO(磁盤/網(wǎng)絡(luò)),等待硬件完成。

3、內(nèi)核如何與硬件交互

1、內(nèi)核的緩存機制

Page Cache

當(dāng)用戶讀取文件時,內(nèi)核會先檢查 Page Cache 是否有數(shù)據(jù)。若無數(shù)據(jù),內(nèi)核發(fā)起磁盤IO,將數(shù)據(jù)讀入 Page Cache,再返回給用戶。

網(wǎng)絡(luò)棧緩沖區(qū)

當(dāng)用戶程序發(fā)送網(wǎng)絡(luò)數(shù)據(jù)時,內(nèi)核將數(shù)據(jù)寫入TCP 發(fā)送緩沖區(qū),由網(wǎng)絡(luò)協(xié)議棧異步發(fā)送。

2、硬件IO流程

更多關(guān)于I/O介紹,可參考:不同網(wǎng)絡(luò)I/O模型的原理

1、磁盤IO

內(nèi)核通過塊設(shè)備驅(qū)動(如ext4文件系統(tǒng)的驅(qū)動)與硬盤通信。數(shù)據(jù)通過DMA(直接內(nèi)存訪問)傳輸,繞過CPU,提高效率。

2、網(wǎng)絡(luò)IO

內(nèi)核通過網(wǎng)卡驅(qū)動與網(wǎng)卡通信。數(shù)據(jù)通過零拷貝技術(shù)(如sendfile()直接從磁盤到網(wǎng)卡,減少內(nèi)存拷貝。

4.2. 線程與進程的實現(xiàn)

輕量級進程(LWP):Java線程對應(yīng)內(nèi)核線程(1:1模型,通過clone()系統(tǒng)調(diào)用創(chuàng)建)

調(diào)度時機

  • 時間片耗盡(內(nèi)核態(tài)時鐘中斷觸發(fā))
  • 主動讓出CPU(如Thread.yield()最終調(diào)用sched_yield())
  • 上下文切換成本:約1~10μs(需切換頁表、寄存器、TLB等)

4.3、網(wǎng)絡(luò)IO的特殊性

1、網(wǎng)絡(luò)數(shù)據(jù)傳輸流程

用戶程序調(diào)用send():

  • 數(shù)據(jù)寫入用戶緩沖區(qū)(如 Java 的BufferedOutputStream)。
  • 達到閾值后,觸發(fā)系統(tǒng)調(diào)用send(),進入內(nèi)核態(tài)。

內(nèi)核處理

  • 數(shù)據(jù)被復(fù)制到TCP 發(fā)送緩沖區(qū)(內(nèi)核態(tài))。
  • 網(wǎng)絡(luò)協(xié)議棧異步將數(shù)據(jù)發(fā)送到網(wǎng)卡。

接收數(shù)據(jù)

  • 網(wǎng)卡接收到數(shù)據(jù)包后,通過中斷通知內(nèi)核。
  • 內(nèi)核將數(shù)據(jù)寫入TCP 接收緩沖區(qū)(內(nèi)核態(tài))。
  • 用戶程序調(diào)用recv()時,內(nèi)核將數(shù)據(jù)復(fù)制到用戶緩沖區(qū)。

5、注意事項

5.1. 減少模式切換的開銷

  • 批量IO:使用NIO的Selector合并就緒事件(單次系統(tǒng)調(diào)用處理多通道)
  • 減少不必要的系統(tǒng)調(diào)用:如合并小文件操作為批量操作
  • 內(nèi)存映射文件:MappedByteBuffer通過mmap()直接映射文件到用戶空間
  • 合理設(shè)置堆外內(nèi)存:DirectByteBuffer不受GC管理,需注意內(nèi)存泄漏
  • JNI優(yōu)化:避免頻繁跨越JNI邊界(如合并多次本地方法調(diào)用)
  • 謹慎使用本地方法:避免引入不穩(wěn)定因素
  • 線程池大小設(shè)置:考慮系統(tǒng)負載和上下文切換開銷

5.2. 內(nèi)核旁路(Kernel Bypass)技術(shù)

  • DPDK/Netty Epoll:繞過內(nèi)核協(xié)議棧直接操作網(wǎng)卡(需特定驅(qū)動支持)
  • Java的Project Loom:虛擬線程(協(xié)程)減少內(nèi)核線程切換開銷

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

理解這些概念有助于Java開發(fā)者編寫更高效、更穩(wěn)定的應(yīng)用程序,特別是在性能敏感或系統(tǒng)級編程場景中。

相關(guān)文章

  • Jmeter基于JDBC請求實現(xiàn)MySQL數(shù)據(jù)庫測試

    Jmeter基于JDBC請求實現(xiàn)MySQL數(shù)據(jù)庫測試

    這篇文章主要介紹了Jmeter基于JDBC請求實現(xiàn)MySQL數(shù)據(jù)庫測試,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-10-10
  • 簡要分析Java多進程編程的并發(fā)控制

    簡要分析Java多進程編程的并發(fā)控制

    這篇文章介紹了簡要分析Java多進程編程的并發(fā)控制,主要針對內(nèi)存獲取方面,需要的朋友可以參考下
    2015-11-11
  • SpringBoot預(yù)加載與懶加載實現(xiàn)方法超詳細講解

    SpringBoot預(yù)加載與懶加載實現(xiàn)方法超詳細講解

    Spring一直被詬病啟動時間慢,可Spring/SpringBoot是輕量級的框架。因為當(dāng)Spring項目越來越大的時候,在啟動時加載和初始化Bean就會變得越來越慢,很多時候我們在啟動時并不需要加載全部的Bean,在調(diào)用時再加載就行,那這就需要預(yù)加載與懶加載的功能了
    2022-11-11
  • SpringBoot中內(nèi)置的49個常用工具類使用

    SpringBoot中內(nèi)置的49個常用工具類使用

    SpringBoot以其強大的自動配置和豐富的生態(tài)系統(tǒng)成為Java開發(fā)的首選框架,本文將介紹49個常用工具類,并通過簡潔的代碼示例展示它們的基本用法,希望對大家有一定的幫助
    2025-04-04
  • 使用java獲取md5值的兩種方法

    使用java獲取md5值的兩種方法

    本篇文章是對使用java獲取md5值的兩種方法進行了詳細的分析介紹,需要的朋友參考下
    2013-06-06
  • Idea Project文件目錄不見了,只剩External Libraries和imi文件的解決

    Idea Project文件目錄不見了,只剩External Libraries和imi文件的解決

    這篇文章主要介紹了Idea Project文件目錄不見了,只剩External Libraries和imi文件的解決方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • Java如何獲取客戶端mac地址

    Java如何獲取客戶端mac地址

    在用戶登錄時,通過獲取IP地址來識別計算機的MAC地址,然后將用戶賬號與該MAC地址進行綁定,確保每個賬號只能在一臺特定的計算機上登錄,增強系統(tǒng)安全性,這種方法適用于需要嚴格賬戶安全管理的場景
    2024-09-09
  • java通過HTTP接收json詳細實例代碼

    java通過HTTP接收json詳細實例代碼

    Java作為一門廣泛使用的編程語言,很多開發(fā)人員會用它來進行http請求,獲取json數(shù)據(jù),這篇文章主要給大家介紹了關(guān)于java通過HTTP接收json的相關(guān)資料,需要的朋友可以參考下
    2023-11-11
  • springboot3整合knife4j詳細圖文教程(swagger增強)

    springboot3整合knife4j詳細圖文教程(swagger增強)

    開發(fā)api提供對應(yīng)的接口規(guī)范進行聯(lián)調(diào)或并行開發(fā),api文檔管理必不可少,常用的Knife4j基于swagger(依賴已經(jīng)compile),可以進行管理,下面這篇文章主要給大家介紹了關(guān)于springboot3整合knife4j的相關(guān)資料,需要的朋友可以參考下
    2024-03-03
  • springMVC盜鏈接詳解

    springMVC盜鏈接詳解

    這篇文章主要為大家詳細介紹了SpringMVC盜鏈接詳解,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能給你帶來幫助
    2021-07-07

最新評論