【Linux】第二十七站:內存管理與文件頁緩沖區

文章目錄

  • 一、物理內存和磁盤交換數據的最小單位
  • 二、操作系統如何管理內存
  • 三、文件的頁緩沖區
  • 四、基數樹or基數(字典樹)
  • 五、總結

一、物理內存和磁盤交換數據的最小單位

image-20231204201348600

我們知道系統當中除了進程管理、文件管理以外,還有內存管理

內存的本質就是對數據的一種臨時存取,所以我們可以把內存看作一個非常大的緩沖區就可以了。

當內存需要數據的時候,可以直接從磁盤中讀取,不需要的時候可以直接釋放或者與磁盤進行交換

image-20231204202436014

為了方便物理內存與磁盤進行交互,我們會將物理內存看作一個一個的小格子,內存也是一種線性的。這個一個個的小單位是4KB

image-20231204202810807

像我們平時形成的可執行程序也是一個一個的以4KB為單位的小的數據段。

也就是說,如果一個可執行程序是4M,那么其實這個可執行程序也是4KB,4KB進行劃分的。這是因為文件系統中數據塊的大小就是4KB。

所以可執行程序在文件系統中天然就是每讀一個塊就是4KB

image-20231204203027361

而我們就將物理內存的這一個個4KB就叫做頁框,將磁盤當中的這一個個4KB叫做頁幀

image-20231204203413702

那么為什么必須是4KB,可以是1KB,2KB嗎?

當然是可以的,不過這樣我們需要修改操作系統的底層源代碼。最終重新編譯操作系統

而我們為什么要選擇4KB呢,我們的文件壓根可能就沒有4KB。可能就是1KB,那么那3KB就浪費了。即便某個文件只有一個比特位,我們也不能只拿這1個比特位,必須將這4KB全部加載進來。

我們知道磁盤本身就是一個機械設備,注定了它IO時候訪問的周期比較長,即比較慢,一次4KB很顯然要比一次1KB效率要更高一些。(因為只需要磁頭定位一次即可。比要定位四次快得多)

其次就是計算機中存在著局部性原理:在訪問某些代碼和數據時候,它附近的代碼和數據也有很大概率被訪問。而且因為機械運動才是慢的主要矛盾,有可能我們的文件只有100字節,但是我們也要讀取4KB,這兩個的效率其實差不多。而且100字節可能更加分散,需要更加精細

所以就有了基于局部性原理的預加載機制

  1. 它可以減少IO的次數,從而對系統整體進行提速 ----硬件

  2. 基于局部性原理,有了預加載機制 ----軟件

注意這里的4KB是物理內存和磁盤交換數據的單位

二、操作系統如何管理內存

在操作系統層面上,要管理內存,肯定會用到虛擬地址。

而操作系統管理內存,也肯定是能看到內存的物理地址的。

那么操作系統如何管理內存呢??

先描述后組織

所以在操作系統里面肯定有一個東西

struct page
{//page頁必要的屬性信息。
};

? 像我們的系統如果有4GB的內存的話,那么最終會存在1024*1024*\1024*4 /4/1024,即約100萬多個頁。

然后我們在操作系統內核里面直接定義

struct page mem_array[1048579]

所以我們發現對內存的管理變為了對數組的管理。

即先描述后組織

而我們知道數組是天然有下標的,所以我們就天然的有了頁號的概念

所以以后當有了一個地址以后,我們就可以知道它是在哪一個頁號上的

因為4KB,需要用12位

所以我們只需要將這個低12位全部清零即可

比如0x11223344,我們直接讓他按位與上0xFFFFF000

所以它最終的頁號就是0x11223000

所以我們就直接用這個頁號就找到了對應的屬性

所以,我們要訪問一個內存,我們只需要先直接找到這個4KB對應的Page,就能在系統中找到對應的物理頁框

在我們系統中,所有申請內存的動作,都是在訪問內存Page數組

而且這個Page結構體不會很大,因為會有一個Page類型的數組,它最終也是要在內存中存放著的,所以它不能太大,所以這也再次說明了前面的頁框大小不能太小,因為它越小,這個數組就越大,占據的內存空間越大。

如下所示,它的page里面都是一些union,這個flags代表它的使用狀態。(每一個比特位都有它的含義,比如當我要使用這個頁框的時候,我們只需要判斷其中的一個標志位是否為0,如果為0那么改為1,這個內存就被使用了)。下面的這個count代表的就是引用計數。用來判斷該內存被多少人使用。

image-20231204212533812

同時在這個Page中還有一個lru,它是最近最少使用。也就是說操作系統會將最近最少使用的東西拿出來給刷新出去。

image-20231204213014901

三、文件的頁緩沖區

如下圖所示

在我們開機的時候,不僅僅是為我們創建了進程了,內存管理做好了等等。

還會將我們文件系統相關的數據都已經預加載到內存了,尤其是Super Block等這些文件系統相關的信息

image-20231205154712705

我們可能會說,那在操作系統上存在著很多分區,這也無所謂,因為可以用鏈表將他們組織起來

image-20231205155052716


如下是一個操作系統,里面有進程、files_struct等內核數據結構

image-20231205155603366

所以最終操作系統上層用的都是fd文件描述符

當我們在打開文件的時候,我們必須知道這個文件的路徑+文件名,然后我們就能讀取當前目錄的數據塊,從而找到文件的inode

因為這些inode Bitmap,Block Bitmap已經被提前加載到內存中了。然后我們確認這個inode是否存在,如果存在,直接將這個inode給加載進來,最后也就能讀取到對應的數據塊了。

以上都是一個文件被加載到內存當中的過程。

而現在我們關心的是這兩件東西:文件的屬性+文件的內容

所以我們需要做的就是,文件的屬性如何被拿到。

我們知道文件的屬性都在inode里面,struct file里面也有文件的屬性,不過只有少量的屬性。

所以我們會創建一個內核數據結構,struct inode,然后直接將磁盤中的inode里面的內容填寫到這個內核數據結構中。而這個struct file是可以找到struct inode的

image-20231205161404122

可是我們之前說過,我們在上層調用fprintf以后,就會通過這個fd,往對應進程中找到對應的文件描述符,從而去找到struct file結構體。那么在這里如何將數據寫到磁盤中呢?

我們現在只能去找到文件的屬性

其實在struct file里面還存在一個結構叫做address_space。

image-20231205162743341

而radix_tree_root它是一顆多叉樹

它結點里面是這樣的結構

image-20231205172031647

如下圖所示,它的每一個葉子結點都指向一個struct page對象,而這樣的每一個struct page對象都對應著4KB的內存大小

image-20231205172537588

所以說當我們將數據拷貝到struct file以后,就會找到address_space,然后一路找到這棵樹的葉子節點中,最終通過這個葉子節點的struct page去管理對應的內存

而上面這個就是文件的頁緩沖區

四、基數樹or基數(字典樹)

在Linux中,我們的每一個進程,打開的每一個文件都要有自己的inode屬性和自己的文件頁緩沖區

什么是字典樹呢?

類似于下面的26叉樹每個結點可以指向26個字母

image-20231205174034476

我們可以用下面這個3個字母簡單的來代替

image-20231205174230362

當我們要查找某個對象的時候,我們可以用bbb來作為key值,從而找到某個對象

image-20231205174428285

文件的內容按照4kb是有偏移量的

比如一個10MB的文件,它占據的內存就是10*1024*1024

而文件的內容是按照4KB一塊一塊的進行存儲著的

image-20231205175531801

而這剛好就是2560塊

所以我們就可以給他進行編號[1,2560]

而每一塊乘以4KB就是他們的相對于原始數據的偏移量

所以前面的這一批數字[1,2560]它剛好每一個編號都是一個int類型的

而int類型是占據32位的

比如有一個數據是0xFF FF FF FF

這個整數我們可以將第一個數字看作一個b,第二個數字看作一個c,第三個數字看作一個a

如果我們可以像前面那樣構建出一顆字典樹

我們就可以利用這個文件的內容所在的區域

就可以利用字典樹,找到對應的page的映射關系。


所以當我們進行讀寫文件的時候,從開頭讀,每一個讀寫都有偏移量。

根據這個偏移量,就可以將這個偏移量轉化為樹中的某一個page

這樣我們就可以根據它的page偏移量,就確定先刷新哪一個page,后刷新哪一個page,就可以讓文件有序的進行刷新了

最終我們的數據就成功的寫入到了內存中

當我們將數據寫入到了內存中以后,后序數據從內存如何寫入到磁盤,就不是操作系統需要關心的事情了,這就導致了當我們突然斷電以后,內存里面的數據都無法保存起來

上面的這個從內存刷新到磁盤當中的過程就是驅動層的事情了, 需要IO子系統來進行完成

五、總結

總之上面的過程其實就是下面的這張圖

也就是說,操作系統里面也有一個文件緩沖區,最后它會被刷新到磁盤上去

image-20231205183319960

上面的過程,我們就把打開文件和文件系統的文件 產生關聯了!

我們也可以發現,這里一共要經歷三次拷貝,第一次將數據寫入到C語言緩沖區中,第二次將數據從C語言緩沖區寫入到文件緩沖區中,第三次是寫在磁盤當中去

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/212363.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/212363.shtml
英文地址,請注明出處:http://en.pswp.cn/news/212363.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

思科最新版Cisco Packet Tracer 8.2.1安裝

思科最新版Cisco Packet Tracer 8.2.1安裝 一. 注冊并登錄CISCO賬號二. 下載 Cisco Packet Tracer 8.2.1三. 安裝四. 漢化五. cisco packet tracer教學文檔六. 正常使用圖 前言 這是我在這個網站整理的筆記,有錯誤的地方請指出,關注我,接下來還會持續更新…

[香橙派]orange pi zero 3 燒錄Ubuntu系統鏡像——無需HDMI數據線安裝

一、前言 本文我們將介紹如何使用orange pi zero 3 安裝Ubuntu系統,本文相關步驟均參考自開發手冊。 二、實施準備 根據開發手冊中所提到的,我們應該擁有如下配件: 1.orange pi zero 3 開發板 2.TF 卡——最小 8GB 容量的 class10 級或以上的高速閃迪卡。…

鴻蒙OS應用開發之語句

在程序開發中,已經有上面的運算符和數據類型了,可以滿足了大部的需求,但是這些程序還是比較簡單的計算和邏輯運算,如果需要復雜的計算和邏輯處理,就需要采用復雜邏輯程序塊來處理了,也就是復雜條件語句才能…

nn.Sequential|nn.ModuleDict|nn.ModuleList 詳解

文章目錄 1、簡介2、三者之間的區別3、如何讓nn.ModuleList 和nn.ModuleDict實現推理3.1 方案1: 實現forward函數3.2 方案2: 將nn.ModuleList 和nn.ModuleDict轉換為nn.Sequential4、nn.ModuleDict、nn.ModuleList 的區別5、nn.ModuleList 、 nn.ModuleDict 與 Python list、…

模型 心流

本系列文章 主要是 分享模型,涉及各個領域,重在提升認知。完全投入其中。 1 心流的應用 1.1 優秀運動員的心流體驗 邁克爾喬丹(Michael Jordan):籃球之神喬丹在比賽中經常進入心流狀態,他曾表示&#xff…

DIY手工藝作坊網站建設的作用如何

我國文化悠久流長,很多手工藝品制作技術放在如今依然有很高的需求度,加之現代新增的技藝,樣式多且藝術性強,比如常見的陶器手工制作技術,當然還有更多。 而對相關作坊來說,除了藝術傳承外,還需…

接觸剛性環境任務下的機器人力控(阻抗)性能測試

內涵 接觸剛性環境任務下的機器人力控(阻抗)性能測試旨在評估機器人在與剛性物體交互時的性能表現。這種測試通過調整機器人的控制參數,如期望剛度和期望阻尼等,并分析記錄的數據,旨在確保機器人能夠在執行任務時保持…

短劇分銷小程序/APP開發:開啟短劇收益時代

今年,短劇火爆出圈,市場規模將達至200億元至300億元。國內全全平臺付費短劇日充值金額為6000萬元,短劇作為一種“快餐式”文化迅速爆火。 短劇契合了觀眾娛樂時間碎片化的發展趨勢,相比于傳統的電視劇,短劇節奏快、劇…

Nacos源碼解讀10——配置中心的客戶端怎么處理服務端推送的配置信息變更

自動裝配 SpringBoot 自動裝配機制 加載 WEB/INF spring.factories org.springframework.cloud.bootstrap.BootstrapConfiguration\ com.alibaba.cloud.nacos.NacosConfigBootstrapConfigurationjava Configuration(proxyBeanMethods false) ConditionalOnProperty(name &q…

MongoDB的連接數據庫,創建、刪除數據庫,創建、刪除集合命令

本文主要介紹MongoDB的連接數據庫,創建、刪除數據庫,創建、刪除集合命令。 目錄 MongoDB連接數據庫連接到本地 MongoDB 實例連接到遠程 MongoDB 實例 MongoDB創建和刪除數據庫MongoDB創建和刪除集合創建集合刪除集合 MongoDB連接數據庫 連接 MongoDB 數…

P1317 低洼地題解

題目 一組數,分別表示地平線的高度變化。高度值為整數,相鄰高度用直線連接。找出并統計有多少個可能積水的低洼地? 如圖:地高變化為 [0,1,0,2,1,2,0,0,2,0]。 輸入輸出格式 輸入格式 兩行,第一行n, 表示有n個數。第…

Spark DataFrame和Dataset使用例子

文章目錄 1、基本操作1.1、創建SparkSession1.2、創建DataFrames1.3、創建Dataset操作1.4、運行sql查詢1.5、創建全局臨時視圖1.6、創建Datasets1.7、與rdd進行互操作1.7.1、使用反射推斷模式1.7.2、以編程方式指定模式 2、完整的測試例子 1、基本操作 1.1、創建SparkSession …

openGauss學習筆記-151 openGauss 數據庫運維-備份與恢復-物理備份與恢復之gs_basebackup

文章目錄 openGauss學習筆記-151 openGauss 數據庫運維-備份與恢復-物理備份與恢復之gs_basebackup151.1 背景信息151.2 前提條件151.3 語法151.4 示例151.5 從備份文件恢復數據 openGauss學習筆記-151 openGauss 數據庫運維-備份與恢復-物理備份與恢復之gs_basebackup 151.1 …

NeuralKG運行備忘

環境配置: conda create -n neuralkg python3.8 conda activate neuralkg pip install torch1.9.1cu111 -f https://download.pytorch.org/whl/torch_stable.html pip install dgl-cu111 dglgo -f https://data.dgl.ai/wheels/repo.html pip install neuralkg! co…

基于java swing 藥品銷售管理系統

大家好,我是DeBug,很高興你能來閱讀!作為一名熱愛編程的程序員,我希望通過這些教學筆記與大家分享我的編程經驗和知識。在這里,我將會結合實際項目經驗,分享編程技巧、最佳實踐以及解決問題的方法。無論你是…

短視頻賬號剪輯矩陣+無人直播系統源頭開發

抖去推爆款視頻生成器,通過短視頻矩陣、無人直播,文案引流等,打造實體商家員工矩陣、用戶矩陣、直播矩陣,輔助商家品牌曝光,團購轉化等多功能賦能商家拓客引流。 短視頻矩陣通俗來講就是批量剪輯視頻和批量發布視頻&am…

Multisim電路仿真軟件使用教程

安裝直接參考這篇文章:Multisim 14.0安裝教程 軟件管家公眾號里有很多軟件,需要的可以去找下然后安裝,這里用的是14.0版本。 這里有個大神的詳細教程,可以參考: Multisim軟件使用詳細入門教程(圖文全解&…

Java Docker 生產環境部署

1. 引言 隨著容器化技術的廣泛應用,Docker成為了一種非常流行的容器化解決方案。Java作為一種跨平臺的編程語言,在生產環境中也廣泛使用。本文將介紹如何使用Docker來部署Java應用程序,并探討一些最佳實踐和注意事項。 2. Docker簡介 Dock…

Python房價分析(二)隨機森林分類模型

目錄 1 數據預處理 1.1 房價數據介紹 1.2 數據預處理 1.2.1 缺失值處理 1.2.2異常值處理 1.2.3 數據歸一化 1.2.4 分類特征編碼 2 隨機森林模型 2.1 模型概述 2.2 建模步驟 2.3 參數搜索過程 3模型評估 3.1 模型評估結果 3.2 混淆矩陣 3.3 繪制房價類別三分類的…

面試官:性能測試瓶頸調優你是真的會嗎?

引言:性能瓶頸調優 在實際的性能測試中,會遇到各種各樣的問題,比如 TPS 壓不上去等,導致這種現象的原因有很多,測試人員應配合開發人員進行分析,盡快找出瓶頸所在。 理想的性能測試指標結果可能不是很高&…