現代操作系統基本都采用虛擬內存管理的方式來管理每個進程對內存的訪問,對進程采用虛擬內存的方式進行管理可以避免不同的進程訪問相同的物理內存而造成程序的紊亂。每個進程都維護獨立的一份虛擬地址,例如在32位操作系統中進程A有4GB的虛擬地址可以使用,進程B也有4GB的虛擬地址可以使用,**因此不同進程彼此之間訪問是相互隔離的。**
**注意,進程中的地址稱為“邏輯地址”,也稱“虛擬地址”,需要轉化為實際的內存設備的“物理地址”才能夠使用。**
:-: 
對于內存的管理一般有分段和分頁兩種方式。
## 內存分段
分段式管理將進程中的內存分為不同的段,例如可以分為代碼段、數據段、棧段、堆段等,這也是最早的內存管理方式。這種方式通過**段表**結構來將虛擬內存映射成物理內存。段表中的段表項由(段號,物理段號)組成。虛擬內存的地址由(段號,偏移地址)組成。
:-: 
【參考:小林圖解系統】
采用內存分段的方式有如下的兩個問題:
1. 容易產生內存碎片:內存分段的方式是完整的將應用程序加載進內存中,而且內存的分配還是一大段連續的,這樣就很容易造成一小塊內存一小塊內存存在的問題,這就是內存碎片。
2. 內存交換效率低:Linux系統中有一塊swap的磁盤區域就是用于當內存不夠用的時候將內存換到磁盤中,由于分段式連續且一般都是比較大的一塊空間,所以交換的效率就比較低。
## 內存分頁
這是現在操作系統用得比較多的內存管理方式,將內存分為以4KB大小為單位的內存頁,這樣在內存不夠用的時候進行交換時也比較快;同時由于每頁都是比較小的連續4KB的內存空間,也不容易造成內存碎片。
內存分頁使用頁表結構來保存虛擬內存到物理內存的映射關系,通過MMU(內存管理單元)來處理這種映射關系,內存分頁的映射過程如下:
:-: 
虛擬地址組成:(頁號、頁內偏移量)
頁表組成:(虛擬頁號、物理頁號)
**每個進程都有單獨的一份頁表結構來保存進程內虛擬內存到物理內存的映射關系。**
現在操作系統多采用多級頁表的結構,其結構如下:
:-: 
由于“程序局部性原理”,可以使得每次不用生成太多的二級頁表,只需要生成加載進內存的那部分內存空間的二級頁表就行了,**注意一級頁表的范圍是要覆蓋所有物理內存的大小的。**
為了避免地址映射的時候多次讀取內存,因此在CPU內存封裝了TLB(快表)緩存結構,用來緩存最近訪問過的頁表項。
## Linux的內存管理方式
由于CPU現代CPU采用分段+分頁的方式來管理內存的,Linux系統也只能跟隨的CPU來實現。但是Linux將整個物理內存都當成一個段,這樣的話就屏蔽了分段,只用到分頁來管理內存。
Linux一般將一個進程的虛擬內存分為**用戶空間與內核空間。**例如32位操作系統將虛擬內存分為1GB的內核空間和3GB的用戶空間
:-: 
對于每個進程其3GB的用戶空間是自定義的,但是1GB的內核空間是映射到同一塊物理內存的,即內核空間是共享的。
更具體的Linux系統中進程的內存布局如下:
:-: 
以Java進程為例,JVM的堆結構其實是在這里的“堆”分配的一塊空間,“堆外內存”也是在這里分配的,只是堆含義的主體對象不同罷了。
【參考】
《小林圖解系統》
- 第一章 Java基礎
- ThreadLocal
- Java異常體系
- Java集合框架
- List接口及其實現類
- Queue接口及其實現類
- Set接口及其實現類
- Map接口及其實現類
- JDK1.8新特性
- Lambda表達式
- 常用函數式接口
- stream流
- 面試
- 第二章 Java虛擬機
- 第一節、運行時數據區
- 第二節、垃圾回收
- 第三節、類加載機制
- 第四節、類文件與字節碼指令
- 第五節、語法糖
- 第六節、運行期優化
- 面試常見問題
- 第三章 并發編程
- 第一節、Java中的線程
- 第二節、Java中的鎖
- 第三節、線程池
- 第四節、并發工具類
- AQS
- 第四章 網絡編程
- WebSocket協議
- Netty
- Netty入門
- Netty-自定義協議
- 面試題
- IO
- 網絡IO模型
- 第五章 操作系統
- IO
- 文件系統的相關概念
- Java幾種文件讀寫方式性能對比
- Socket
- 內存管理
- 進程、線程、協程
- IO模型的演化過程
- 第六章 計算機網絡
- 第七章 消息隊列
- RabbitMQ
- 第八章 開發框架
- Spring
- Spring事務
- Spring MVC
- Spring Boot
- Mybatis
- Mybatis-Plus
- Shiro
- 第九章 數據庫
- Mysql
- Mysql中的索引
- Mysql中的鎖
- 面試常見問題
- Mysql中的日志
- InnoDB存儲引擎
- 事務
- Redis
- redis的數據類型
- redis數據結構
- Redis主從復制
- 哨兵模式
- 面試題
- Spring Boot整合Lettuce+Redisson實現布隆過濾器
- 集群
- Redis網絡IO模型
- 第十章 設計模式
- 設計模式-七大原則
- 設計模式-單例模式
- 設計模式-備忘錄模式
- 設計模式-原型模式
- 設計模式-責任鏈模式
- 設計模式-過濾模式
- 設計模式-觀察者模式
- 設計模式-工廠方法模式
- 設計模式-抽象工廠模式
- 設計模式-代理模式
- 第十一章 后端開發常用工具、庫
- Docker
- Docker安裝Mysql
- 第十二章 中間件
- ZooKeeper