golang-GetPagesize()記憶體頁的介紹-記憶體分頁大小對效能的提升原理

來源:互聯網
上載者:User

JVM最佳化之調整大記憶體分頁(LargePage)

本文將從記憶體分頁的原理,如何調整分頁大小兩節內容,向你闡述LargePage對JVM的效能有何提升作用,並在文末點明了大內分頁的副作用。OK,讓我們開始吧!

記憶體分頁大小對效能的提升原理

首先,我們需要回顧一小部分電腦群組成原理,這對理解大記憶體分頁至於JVM效能的提升是有好處的。

什麼是記憶體分頁?
我們知道,CPU是通過定址來訪問記憶體的。32位CPU的定址寬度是 0~0xFFFFFFFF ,計算後得到的大小是4G,也就是說可支援的實體記憶體最大是4G。

但在實踐過程中,碰到了這樣的問題,程式需要使用4G記憶體,而可用實體記憶體小於4G,導致程式不得不降低記憶體佔用。
為瞭解決此類問題,現代CPU引入了 MMU(Memory Management Unit 記憶體管理單元)。

MMU 的核心思想是利用虛擬位址替代物理地址,即CPU定址時使用虛址,由 MMU 負責將虛址映射為物理地址。
MMU的引入,解決了對實體記憶體的限制,對程式來說,就像自己在使用4G記憶體一樣。

記憶體分頁(Paging)是在使用MMU的基礎上,提出的一種記憶體管理機制。它將虛擬位址和物理地址按固定大小(4K)分割成頁(page)和頁幀(page frame),並保證頁與頁幀的大小相同。

這種機制,從資料結構上,保證了訪問記憶體的高效,並使OS能支援非連續性的記憶體配置。
在程式記憶體不夠用時,還可以將不常用的實體記憶體頁轉移到其他存放裝置上,比如磁碟,這就是大家耳熟能詳的虛擬記憶體。

在上文中提到,虛擬位址與物理地址需要通過映射,才能使CPU正常工作。
而映射就需要儲存映射表。在現代CPU架構中,映射關係通常被儲存在實體記憶體上一個被稱之為頁表(page table)的地方。
如:

實體記憶體之間的互動關係

從這張圖中,可以清晰地看到CPU與頁表,實體記憶體之間的互動關係。

進一步最佳化,引入TLB(Translation lookaside buffer,頁表寄存器緩衝) 由上一節可知,頁表是被儲存在記憶體中的。我們知道CPU通過匯流排訪問記憶體,肯定慢於直接存取寄存器的。
為了進一步最佳化效能,現代CPU架構引入了TLB,用來緩衝一部分經常訪問的頁表內容。
如:

加入了TLB實體記憶體之間的互動關係

對比 9.6 那張圖,在中間加入了TLB。

為什麼要支援大記憶體分頁?
TLB是有限的,這點毫無疑問。當超出TLB的儲存極限時,就會發生 TLB miss,之後,OS就會命令CPU去訪問記憶體上的頁表。如果頻繁的出現TLB miss,程式的效能會下降地很快。

為了讓TLB可以儲存更多的頁地址映射關係,我們的做法是調大記憶體分頁大小。

如果一個頁4M,對比一個頁4K,前者可以讓TLB多儲存1000個頁地址映射關係,效能的提升是比較可觀的。

調整OS和JVM記憶體分頁

在Linux和windows下要啟用大記憶體頁,有一些限制和設定步驟。

Linux:
限制:需要2.6核心以上或2.4核心已打大記憶體頁補丁。
確認是否支援,請在終端敲如下命令:

cat /proc/meminfo | grep Huge

HugePages_Total: 0
HugePages_Free: 0
Hugepagesize: 2048 kB

如果有HugePage字樣的輸出內容,說明你的OS是支援大記憶體分頁的。Hugepagesize就是預設的大記憶體頁size。
接下來,為了讓JVM可以調整大記憶體頁size,需要設定下OS 共用記憶體段最大值 和 大記憶體頁數量。

共用記憶體段最大值
建議這個值大於Java Heap size,這個例子裡設定了4G記憶體。

echo 4294967295 > /proc/sys/kernel/shmmax

大記憶體頁數量

echo 154 > /proc/sys/vm/nr_hugepages

這個值一般是 Java進程佔用最大記憶體/單個頁的大小 ,比如java設定 1.5G,單個頁 10M,那麼數量為 1536/10 = 154。
注意:因為proc是記憶體FS,為了不讓你的設定在重啟後被衝掉,建議寫個指令碼放到 init 階段(rc.local)。

Windows:
限制:僅支援 windows server 2003 以上server版本
操作步驟:

  1. Control Panel -> Administrative Tools -> Local Security Policy
  2. Local Policies -> User Rights Assignment
  3. 雙擊 “Lock pages in memory”, 添加使用者和組
  4. 重啟電腦

注意: 需要管理員操作。

單個頁大小調整
JVM啟用時加參數 -XX:LargePageSizeInBytes=10m
如果JDK是在1.5 update5以前的,還需要手動加 -XX:+UseLargePages,作用是啟用大記憶體頁支援。

大記憶體分頁的副作用

因為每頁size變大了,導致JVM在計算Heap內部分區(perm, new, old)記憶體佔用比例時,會出現超出正常值的劃分。最壞情況下是,某個區會多佔用一個頁的大小。不過後續jvm版本也在調整這個策略。

一般情況,不建議將頁size調得太大,4-64M,是可以接受的(預設是4M)。為了合理設定這個值,你應該對你的系統做一下benchmark。
說實話,網上我見過調得最猛的,有調到256M,從benchmark報表上看,效能不是太壞。如果你有64位的大記憶體機器,不妨嘗試一下。

另外,網上有很多GC調優的文章內容中都有提到 LargePageSizeInBytes,但未提任何OS限制。在OS不支援的情況下,設定這個參數,這個參數將僅僅是個擺設。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.