欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

深入了解Android?IO的底層原理

 更新時(shí)間:2022年06月22日 10:27:08   作者:??九心????  
這篇文章主要介紹了深入了解Android?IO的底層原理,IO有緩沖與非緩沖?IO、直接與非直接?IO、阻塞與非阻塞?IO、同步與異步?IO等分類,具體詳情感興趣的小伙伴可以參考下面文章內(nèi)容

前言

最近在看《Linux內(nèi)核設(shè)計(jì)與實(shí)現(xiàn)》的時(shí)候,就想著要不把知識(shí)串聯(lián)一下吧。聊什么呢?今天先來(lái)聊聊 Android IO 的調(diào)用鏈路。說(shuō)起 IO,這可真是一個(gè)很復(fù)雜的過(guò)程,里面涉及了很多內(nèi)容,先是軟件,最后到硬件,用一張圖來(lái)表示一下吧:

IO結(jié)構(gòu).jpeg

本文打算簡(jiǎn)單得和大伙討論一下 IO 的流程。

一、應(yīng)用層

作為應(yīng)用開(kāi)發(fā)者,我們通常是 IO 發(fā)起點(diǎn),比如用戶說(shuō)這本小說(shuō)很好看,我要下載到本地,或者,這張圖拍的不錯(cuò),分享給你看一下。

雖然這些都是常見(jiàn)的 IO 場(chǎng)景,但是你知道有哪些 IO 嗎?

1. IO的分類

通常去使用 IO 的時(shí)候,我們會(huì)有很多種選擇,常見(jiàn)的有:

  • 緩沖與非緩沖 IO
  • 直接與非直接 IO
  • 阻塞與非阻塞 IO
  • 同步與異步 IO

大家平時(shí)可能也就聽(tīng)過(guò)緩沖 IO 和 阻塞 IO,這些可能是我們平時(shí)開(kāi)發(fā)可能涉及到的。

1.1 緩沖和直接

前兩種分類都是使用緩存的。

緩沖是針對(duì)標(biāo)準(zhǔn)庫(kù)的。

Linux 標(biāo)準(zhǔn)庫(kù)定義了很多操作系統(tǒng)的基礎(chǔ)服務(wù),比如輸入/輸出、字符串處理等等。Android 操作系統(tǒng)的標(biāo)準(zhǔn)庫(kù)是 Bionic,它可是應(yīng)用層聯(lián)系內(nèi)核的橋梁,我們也可以通過(guò) NDK 訪問(wèn) Bionic。

使用標(biāo)準(zhǔn)庫(kù)進(jìn)行 IO 我們稱為緩沖 IO,我們讀文件的時(shí)候,經(jīng)常遇到,讀完一行才會(huì)讓輸出,在 Android 內(nèi)部也做了類似的處理。

直接是針對(duì)內(nèi)核的。

使用 Binder 跨進(jìn)程傳遞數(shù)據(jù)的時(shí)候,需要將數(shù)據(jù)從用戶空間傳遞到內(nèi)核空間,非直接 IO 也這樣,內(nèi)核空間會(huì)多做一層頁(yè)緩存,如果做直接 IO,應(yīng)用程序會(huì)直接調(diào)用文件系統(tǒng)。

緩沖和非直接 IO 就像 IO 調(diào)度的一級(jí)和二級(jí)緩存,為什么要做這么多緩存呢?因?yàn)椴僮鞔疟P(pán)本身就是消耗資源的,不加緩存頻繁 IO 不僅會(huì)耗費(fèi)資源也會(huì)耗時(shí)。

1.2 阻塞和異步

同步和異步我想大家都了解什么意思。

阻塞 IO指的是當(dāng)用戶執(zhí)行讀寫(xiě)的時(shí)候,線程會(huì)一直阻塞,數(shù)據(jù)準(zhǔn)備和將數(shù)據(jù)拷貝到用戶進(jìn)程都是阻塞的

Java 中的 NIO 是非阻塞 IO,當(dāng)用戶發(fā)起讀寫(xiě)的時(shí)候,線程不會(huì)阻塞,之后,用戶可以通過(guò)輪詢或者接受通知的方式,獲取當(dāng)前 IO 調(diào)度的結(jié)果:

即使是非阻塞 IO,對(duì)于讀數(shù)據(jù)來(lái)說(shuō),也只有準(zhǔn)備數(shù)據(jù)的過(guò)程是異步,將數(shù)據(jù)從內(nèi)核拷貝到用戶進(jìn)程這個(gè)過(guò)程還是同步的。所以非阻塞 IO 不能算是真正意義上的異步 IO。

真正的異步 IO 應(yīng)該是這樣的:

準(zhǔn)備數(shù)據(jù)和將數(shù)據(jù)拷貝從內(nèi)核到用戶進(jìn)程都應(yīng)該是異步的,當(dāng)收到通知的的時(shí)候,我們已經(jīng)可以在應(yīng)用進(jìn)程使用數(shù)據(jù)了。

2. IO流程

作為應(yīng)用層開(kāi)發(fā),大家做 IO 的場(chǎng)景并不多,最多也就是使用 BufferedInputStream 和 BufferedOutputStream 讀寫(xiě)文件,至于 NIO ,那就更少見(jiàn)了。

我們了解一下阻塞 IO 的讀調(diào)用流程。

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

應(yīng)用層調(diào)完了,下面會(huì)直接進(jìn)入內(nèi)核嗎?

除去直接 IO,大部分都不會(huì)!用戶空間和內(nèi)核之間隔著一個(gè)系統(tǒng)調(diào)用(sysCall),它的作用如下:

  • 給用戶空間提供抽象的訪問(wèn)硬件的接口:比如申請(qǐng)系統(tǒng)資源、操作設(shè)備讀寫(xiě)等
  • 保證系統(tǒng)的安全和穩(wěn)定:內(nèi)核可以對(duì)用戶進(jìn)程的訪問(wèn)做出一些裁決,防止用戶進(jìn)程做出一些危害系統(tǒng)的事情

畢竟內(nèi)核很復(fù)雜,抽象出通用的接口,可以防止用戶空間的進(jìn)程僭越,獲取到它不該獲取的內(nèi)容。

為了能夠讓?xiě)?yīng)用進(jìn)程聯(lián)系上內(nèi)核,它會(huì)通過(guò)一個(gè)軟中斷,通知內(nèi)核,我想調(diào)用內(nèi)核中 sysCall 中的讀接口。

對(duì)于讀 IO,系統(tǒng)調(diào)用中有一個(gè) sys_read 方法與之對(duì)應(yīng),內(nèi)核收到通知執(zhí)行該方法的時(shí)候,就會(huì)執(zhí)行虛擬文件系統(tǒng)的 read 方法。

三、虛擬文件系統(tǒng)

文件系統(tǒng)實(shí)在是太多了,比如我手機(jī)用戶空間的文件系統(tǒng)是 f2fs,系統(tǒng)空間的文件系統(tǒng)是 ext4。對(duì)于應(yīng)用程序來(lái)說(shuō),它就想調(diào)用個(gè)讀方法,不想管你手機(jī)的底層文件系統(tǒng)是什么!

虛擬文件系統(tǒng)就是來(lái)干這活的,它可以屏蔽具體的文件系統(tǒng),定義了一組所有文件系統(tǒng)都支持的數(shù)據(jù)結(jié)構(gòu)和標(biāo)準(zhǔn)接口。這樣,應(yīng)用層的程序員只需了解 VFS 提供的統(tǒng)一接口就行。

虛擬文件系統(tǒng)常被稱為 VFS(Virtual File System),下稱 VFS。

1. VFS結(jié)構(gòu)

VFS 采用的是面向?qū)ο蟮脑O(shè)計(jì)思路,它常常有下列的對(duì)象(C語(yǔ)言中的結(jié)構(gòu)體)構(gòu)成:

這些對(duì)象構(gòu)成了基本的虛擬文件系統(tǒng)。

不過(guò),光有這些對(duì)象可不行,VFS 還得知道如何操作它們,所以,每個(gè)對(duì)象中還存在對(duì)應(yīng)的操作對(duì)象:

  • super_operation 對(duì)象:內(nèi)核針對(duì)超級(jí)塊所能調(diào)用的方法
  • inode_operation 對(duì)象:內(nèi)核針對(duì)索引結(jié)點(diǎn)所能調(diào)用的方法
  • dentry_operation 對(duì)象:內(nèi)核針對(duì)目錄項(xiàng)所能操作的方法
  • file_operation 對(duì)象:內(nèi)核針對(duì)進(jìn)程中打開(kāi)的文件所能操作的方法

大伙最熟悉的應(yīng)該是文件,這是我們能夠在進(jìn)程中實(shí)實(shí)在在能夠操作的,比如,在文件的 file_operation 中,就有我們熟悉的讀、寫(xiě)、拷貝、打開(kāi)、寫(xiě)入磁盤(pán)等方法。

不知道大伙兒有沒(méi)注意到,我特意標(biāo)注了超級(jí)塊和索引節(jié)點(diǎn)存在于內(nèi)存和磁盤(pán),而目錄項(xiàng)和文件只存在于內(nèi)存。

我的理解是對(duì)于磁盤(pán),索引節(jié)點(diǎn)已經(jīng)足夠記錄文件信息,并不需要目錄項(xiàng)再來(lái)記錄層級(jí)關(guān)系;而對(duì)于內(nèi)存來(lái)說(shuō),為了節(jié)省內(nèi)存,只會(huì)把需要用到的文件和目錄項(xiàng)所用到的索引節(jié)點(diǎn)加入內(nèi)存,文件系統(tǒng)只有被掛載的時(shí)候超級(jí)塊才會(huì)被加入到內(nèi)存中。

目錄項(xiàng)、索引節(jié)點(diǎn)、文件和超級(jí)塊結(jié)構(gòu)圖:

上面的結(jié)構(gòu)圖還有幾點(diǎn)要注意一下:

  • 目錄項(xiàng)不等于目錄這個(gè)概念,對(duì)于 /home/pic/a.jpg 來(lái)說(shuō),根目錄 / 、home 目錄、pic 目錄 和 a.jpg 都屬于目錄項(xiàng)
  • 每個(gè)目錄項(xiàng)都會(huì)持有索引節(jié)點(diǎn)的指針
  • 索引節(jié)點(diǎn)包含內(nèi)核在操作文件需要的全部信息,比如存在磁盤(pán)的位置等
  • 進(jìn)程中打開(kāi)的文件持有目錄項(xiàng)

2. VFS中的緩存

結(jié)合本文中的第一張圖,我們會(huì)發(fā)現(xiàn),VFS 有目錄項(xiàng)緩存、索引節(jié)點(diǎn)緩存和頁(yè)緩存,目錄項(xiàng)和索引節(jié)點(diǎn)我們都知道什么意思,那頁(yè)緩存呢?

頁(yè)緩存是由 RAM 中的物理頁(yè)組成的,對(duì)應(yīng)著 ROM 上的物理地址。我們都知道,現(xiàn)在主流 Android 的 RAM 訪問(wèn)速度高達(dá)是 8.5 GB/S,而 ROM 的訪問(wèn)速度最高只有 6400 MB/S,所以訪問(wèn) RAM 的速度要遠(yuǎn)遠(yuǎn)快于 ROM,頁(yè)緩存的目的也在于此。

當(dāng)發(fā)起一個(gè)讀操作的時(shí)候,內(nèi)核會(huì)首先檢查需要的數(shù)據(jù)是否在頁(yè)緩存,如果在,直接從內(nèi)存中讀取,我們稱之為緩存命中;如果不在,那么內(nèi)核在讀取數(shù)據(jù)的時(shí)候,將讀到的數(shù)據(jù)放入頁(yè)緩存,需要注意的是,頁(yè)緩存可以存入全部文件內(nèi)容,也可以僅僅存幾頁(yè)。

3. IO流程

經(jīng)過(guò)系統(tǒng)調(diào)用,讀 IO 進(jìn)入了 VFS。

就去找文件對(duì)象(VFS 中的),通過(guò)文件對(duì)象的 file_operation 對(duì)象,調(diào)用 read 方法,傳入讀取的數(shù)據(jù)量。不過(guò) read 方法也是找到文件對(duì)象對(duì)應(yīng)的目錄項(xiàng),目錄項(xiàng)又找到索引節(jié)點(diǎn),畢竟,只有索引節(jié)點(diǎn)知道文件存在哪兒?

通過(guò)索引節(jié)點(diǎn),內(nèi)核就能唯一確定一個(gè)文件,然后在頁(yè)緩存中尋找是否有自己需要的數(shù)據(jù),找到就直接返回。沒(méi)找到就去進(jìn)行下一步的操作。

四、文件系統(tǒng)

VFS 定義了文件系統(tǒng)的統(tǒng)一接口,具體的實(shí)現(xiàn)了交給了文件系統(tǒng),超級(jí)塊里面的數(shù)據(jù)如何組織、目錄和索引結(jié)構(gòu)如何設(shè)計(jì)、怎么分配和清理數(shù)據(jù),這都是設(shè)計(jì)一個(gè)文件系統(tǒng)必須考慮的!

說(shuō)白了,文件系統(tǒng)就是用來(lái)管理磁盤(pán)里的持久化的數(shù)據(jù)的,對(duì)于 Android 來(lái)說(shuō),最常見(jiàn)的就是 ext4 和 f2fs。

1. 文件系統(tǒng)結(jié)構(gòu)

因?yàn)槲募到y(tǒng)是 VFS 的具體實(shí)現(xiàn),所以同樣有目錄項(xiàng)、索引節(jié)點(diǎn)和超級(jí)塊,上面的圖片用來(lái)描述文件系統(tǒng)也同樣適合。

拿早起 ext2 的系統(tǒng)結(jié)構(gòu)來(lái)講:

每一個(gè) ext2 都由大量的塊組組成,每個(gè)塊組的結(jié)構(gòu)就跟上面的目錄項(xiàng)和索引節(jié)點(diǎn)中的圖一樣??梢钥吹剑?inode 列表,存在著很多數(shù)據(jù)塊,塊是內(nèi)存中最小的尋址單元,見(jiàn)于磁盤(pán)中的章節(jié),一般可以設(shè)置帶大小為 2kb - 64kb 之間。

2. 文件系統(tǒng)的不同點(diǎn)

雖然大部分的文件系統(tǒng)也都有超級(jí)塊、索引節(jié)點(diǎn)和數(shù)據(jù)塊,但是各個(gè)文件系統(tǒng)的實(shí)現(xiàn)卻大不相同,這就導(dǎo)致了他們的側(cè)重點(diǎn)也不一樣。

拿 ext4 和 f2fs 來(lái)講:

  • ext4連續(xù)讀取大文件更強(qiáng),占用的空間更小
  • f2fs隨機(jī) IO 更快

說(shuō)白了,也就是它們對(duì)于空閑空間分配和已有的數(shù)據(jù)管理方式不一致,不同的數(shù)據(jù)結(jié)構(gòu)和算法導(dǎo)致了不同的結(jié)果。

3. IO流程

這里的 IO 流程其實(shí)跟 VFS 差不多,畢竟文件系統(tǒng)是 VFS 的具體實(shí)現(xiàn)。

五、塊IO層

Linux 下面有兩大基本設(shè)備類型:

  • 塊設(shè)備:能夠隨機(jī)訪問(wèn)固定大小數(shù)據(jù)片的硬件設(shè)備,硬盤(pán)和閃存(下面介紹)就是常見(jiàn)的塊設(shè)備
  • 字符設(shè)備:字符設(shè)備只能按照字符流的方式被有序訪問(wèn),比如鍵盤(pán)和串口

這兩個(gè)設(shè)備的區(qū)別就是是否能夠隨機(jī)訪問(wèn)。拿屬于字符設(shè)備的鍵盤(pán)來(lái)說(shuō),當(dāng)我們輸入 Hello World 的時(shí)候,系統(tǒng)肯定不可以先得到得到 eholl wrodl,這樣的話,輸出就亂套了。而對(duì)于閃存來(lái)說(shuō),常常是看完這個(gè)這些數(shù)據(jù)庫(kù)組成的圖片,又要讀間隔很遠(yuǎn)的數(shù)組塊的小說(shuō)內(nèi)容,所以讀取的塊在磁盤(pán)上肯定不是連續(xù)的。

因?yàn)閮?nèi)核管理塊設(shè)備實(shí)在太復(fù)雜了,所以就出現(xiàn)了管理塊設(shè)備的子系統(tǒng),就是上面說(shuō)的文件系統(tǒng)。

1. 塊設(shè)備結(jié)構(gòu)

塊設(shè)備中常用的數(shù)據(jù)管理單位:

  • 扇區(qū):設(shè)備的最小尋址單元
  • 塊:文件系統(tǒng)的最小尋址單元,數(shù)倍大于扇區(qū)
  • 片段:由數(shù)百至數(shù)千的塊組成

因?yàn)?Linux 中常常用的硬盤(pán),這里我有點(diǎn)疑問(wèn),這里的管理單位是否和下面閃存管理單位一致?

2. IO過(guò)程

如果當(dāng)前有 IO 操作,內(nèi)核會(huì)建立一個(gè) bio 結(jié)構(gòu)體的基本容器,它是由多個(gè)片段組成,每一個(gè)片段都是一小塊連續(xù)的內(nèi)存緩沖區(qū)。

之后,內(nèi)核會(huì)將這些 IO 請(qǐng)求保存在一個(gè) request_queue 的請(qǐng)求隊(duì)列中。

如果按照 IO 請(qǐng)求產(chǎn)生的順序發(fā)向塊設(shè)備,性能肯定難以接受,所以內(nèi)核會(huì)按照磁盤(pán)地址對(duì)進(jìn)入隊(duì)列之前提交的 IO 請(qǐng)求做合并與排序的預(yù)操作。

六、磁盤(pán)

移動(dòng)設(shè)備中常用的持久化存儲(chǔ)是 Nand 閃存,UFS 又是 Nand 閃存中的佼佼者,其特點(diǎn)是速度更快、體積小和更省電。

當(dāng)今 Android 旗艦機(jī)基本上標(biāo)配 UFS 3.1,它們只是一塊兒很小的芯片:

閃存是一種非易失性存儲(chǔ)器,即使掉電了,數(shù)據(jù)也不會(huì)丟。閃存的存儲(chǔ)單元從小到大有:

  • Cell(單元):是閃存存儲(chǔ)的最小單位,根據(jù)存儲(chǔ)的數(shù)量可以分為SLC(1bit/Cell)、MLC(2bit/Cell)、TLC(3bit/Cell)和QLC(4bit/Cell)
  • Page(頁(yè)):由大量的 Cell 構(gòu)成,每個(gè) Page 的大小通常是 16 kb,它是閃存能夠讀取的和寫(xiě)入的最小單位
  • Block(塊):每個(gè)塊由數(shù)百至數(shù)千的 Page 組成
  • Plane(面):Plane 由數(shù)百至數(shù)千的 Black 組成
  • Die(邏輯單元):每個(gè) Die 由一個(gè)至多個(gè) Plane,是閃存中可以執(zhí)行命令或者回報(bào)狀態(tài)的最小單元

對(duì)于每個(gè) Cell 來(lái)說(shuō),是由一種類 NMOS 的雙層浮柵 MOS 管組成,大概是這樣:

對(duì)于 SLC(存儲(chǔ)1bit)來(lái)說(shuō):

  • 如果需要1,在 P 極施加一個(gè)電壓,將電子吸出儲(chǔ)存單元
  • 如果需要0,需要在頂層的控制極施加一個(gè)電壓,讓電子吸回存儲(chǔ)單元

這就構(gòu)成了數(shù)據(jù)存儲(chǔ)的最小單位,0和1!

總結(jié)

整個(gè)流程簡(jiǎn)要的用一張圖來(lái)表示:

因?yàn)槲覍?duì)內(nèi)核也不是特別熟,文中難免有不對(duì)的地方,歡迎在評(píng)論區(qū)指正,如果覺(jué)得本文不錯(cuò),「點(diǎn)贊」是最好的肯定!

到此這篇關(guān)于深入了解Android IO的底層原理的文章就介紹到這了,更多相關(guān) Android IO原理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Android自定義可標(biāo)記日歷效果

    Android自定義可標(biāo)記日歷效果

    這篇文章主要為大家詳細(xì)介紹了Android自定義可標(biāo)記日歷效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • Android實(shí)現(xiàn)五子棋游戲(局域網(wǎng)版)

    Android實(shí)現(xiàn)五子棋游戲(局域網(wǎng)版)

    這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)局域網(wǎng)版的五子棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • Android入門(mén)之TextClock的使用教程

    Android入門(mén)之TextClock的使用教程

    TextClock是在Android 4.2(API 17)后推出的用來(lái)替代DigitalClock的一個(gè)控件。本文將為大家詳細(xì)說(shuō)說(shuō)TextClock的使用,感興趣的小伙伴可以了解一下
    2022-11-11
  • Android自定義Camera實(shí)現(xiàn)拍照小功能

    Android自定義Camera實(shí)現(xiàn)拍照小功能

    這篇文章主要為大家詳細(xì)介紹了Android自定義Camera實(shí)現(xiàn)拍照小功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • Android開(kāi)發(fā)之廣播機(jī)制淺析

    Android開(kāi)發(fā)之廣播機(jī)制淺析

    這篇文章主要介紹了Android開(kāi)發(fā)之廣播機(jī)制淺析,主要包括了發(fā)布、接收及配置廣播的實(shí)例,需要的朋友可以參考下
    2014-08-08
  • Android ActivityManagerService啟動(dòng)流程詳解

    Android ActivityManagerService啟動(dòng)流程詳解

    這篇文章主要介紹了Android ActivityManagerService啟動(dòng)流程,AMS,即ActivityManagerService,是安卓java framework的一個(gè)服務(wù),運(yùn)行在system_server進(jìn)程。此服務(wù)十分重要,因?yàn)樗芾碇沧康乃拇蠼M件,是安卓APP開(kāi)發(fā)者最常接觸到的一個(gè)服務(wù)
    2023-02-02
  • Android編程實(shí)現(xiàn)兩點(diǎn)觸控功能示例

    Android編程實(shí)現(xiàn)兩點(diǎn)觸控功能示例

    這篇文章主要介紹了Android編程實(shí)現(xiàn)兩點(diǎn)觸控功能的方法,涉及Android事件響應(yīng)與處理相關(guān)操作技巧,需要的朋友可以參考下
    2017-08-08
  • Android屬性動(dòng)畫(huà)實(shí)現(xiàn)圖片從左到右逐漸消失

    Android屬性動(dòng)畫(huà)實(shí)現(xiàn)圖片從左到右逐漸消失

    這篇文章主要介紹了Android屬性動(dòng)畫(huà)實(shí)現(xiàn)圖片從左到右逐漸消失,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • 協(xié)程作用域概念迭代RxTask?實(shí)現(xiàn)自主控制

    協(xié)程作用域概念迭代RxTask?實(shí)現(xiàn)自主控制

    這篇文章主要為大家介紹了協(xié)程作用域概念迭代RxTask實(shí)現(xiàn)自主控制詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • flutter Toast實(shí)現(xiàn)消息提示框

    flutter Toast實(shí)現(xiàn)消息提示框

    這篇文章主要為大家詳細(xì)介紹了flutter Toast實(shí)現(xiàn)消息提示框,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-07-07

最新評(píng)論