Java程序员需要掌握的计算机底层知识(四):内存管理
內存管理
單進程DOS時代
DOS時代 - 同一時間只能有一個進程在運行(也有一些特殊算法可以支持多進程)
windows9x - 多個進程裝入內存存在的問題:
- 內存不夠用
- 互相打擾
為了解決這兩個問題,誕生了現在的內存管理系統:使用虛擬地址、分頁裝入、軟硬件結合尋址。
將內存分頁(因為內存不夠用),內存中分成固定大小的頁框4K,把硬盤上的程序也分成4K大小的塊。另外維護一個頁框page frame,用到哪一塊,就將哪一塊加載進內存中。
例如,執行QQ.exe時,把它的頁表記錄下來,執行時,用到頁表中的哪一頁,就將這頁加載進內存中。
在加載的過程中,如果內存已經滿了,會把最不常用的一塊放到swap分區, 把最新的一塊加載進來,這個就是著名的LRU算法。這就是交換分區的由來。
LRU算法(解決內存不夠用的問題)
LeetCode 146 題,頭條要求15分鐘內手撕,阿里去年也要求手撕
幾乎所有涉及到緩存的,都用到了LRU(Least Recently Used:最不常用)或LFU算法。
使用LinkedHashMap可以實現 LRU 算法
哈希表(保證查找操作O(1)) + 雙向鏈表 (保證排序操作和新增操作 O(1)))
虛擬內存(解決不同進程內存相互打擾的問題)
以DOS Win31 …這類系統為例,A進程、B進程是可以互相操作內存的。
為了保證互不影響,讓進程工作在虛擬空間。在程序中用到的空間地址不再是直接的物理地址,而是虛擬的地址,這樣,A進程永遠不可能訪問到B進程的空間。
虛擬空間多大呢?
虛擬空間的大小就是尋址空間,要看操作系統是多少位的。
例如,64位系統的虛擬空間是2^64,32為系統的虛擬空間是2^32。
虛擬空間比物理空間大很多 ,單位是 byte
為什么使用虛擬內存?
站在虛擬的角度,進程是獨享整個系統 + CPU
地址是怎么映射的?
內存映射:偏移量 + 段的基地址 = 線性地址 (虛擬空間)
線性地址通過 操作系統 + MMU(硬件 Memory Management Unit內存管理單元)來映射到真正的物理地址。
只有操作系統內核知道虛擬內存中地址對應的真正的物理地址,應用程序是不知道的,這樣保證了系統的安全。
P1,P2,P3,P4都認為自己是獨占整個內核的,實際上是共享操作系統內核。
MMU給每一個進程分配他們的內存資源。
如果內存裝滿了,使用LRU算法將最不常使用的頁放入硬盤的交換空間中。
缺頁中斷
在執行一條指令時,如果發現需要用到頁在內存中沒有,那么停止該指令的執行,并產生一個缺頁異常(中斷),由內核處理并加載,之后,原先引起的異常的指令就可以繼續執行,而不再產生異常。
ZGC 垃圾回收器
算法叫做:Colored Pointer 顏色指針
它的GC信息記錄在指針上,而不是記錄在頭部, immediate memory use
42位指針 尋址空間4T JDK13 將尋址空間擴展到了 16T 目前為止最大16T 2^44
CPU如何區分一個立即數和一條指令?
總線內部分為:數據總線、地址總線、控制總線。從數據總線過來的,就是立即數;從控制總線過來的,就是指令…
因為地址總線目前48位(48根,廠商為了省成本),所以目前ZGC的尋址空間為48-4(用于顏色指針)=44位,也就是 16T = 2^44
顏色指針本質上包含了地址映射的概念
JVM 的很多思想都是來源于Linux的,Linux的很多概念是自創的。
- AQS 來源于 Linux 的 Futex 鎖
- ZGC 的顏色指針思想來源于地址映射
總結
以上是生活随笔為你收集整理的Java程序员需要掌握的计算机底层知识(四):内存管理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 分布式ID业界解决方案
- 下一篇: Java程序员需要掌握的计算机底层知识(