一個java程式的virtual memory 和 resident memory

來源:互聯網
上載者:User

最近吃了virtual memory的苦頭,一直接到報告說我們的產品時不時會重啟,並且報告說是“使用的memory超過了5G”。

重啟是我們產品的機制,我們會監控記憶體,超過一定限度會進行GC並重啟應用,可是超過5G這也太誇張了,而且報告出狀況的環境都沒有多大的負載。這個問題一直被認為是記憶體泄露,苦於無法重現一直無法解決,最近忽然在一個客戶的環境中重現了,趕緊研究!

最終發現我們的監控機制是有問題的:代碼是這樣判斷的, 當 virtual memory > 5 * Xmx(java option) 就會重啟, 看起來沒錯, 但是在使用free命令查看應用運行前後的記憶體size卻發現實際使用的記憶體並不多,並且剩餘記憶體一直保持在一個比較穩定的數字,並沒有持續下降的情況。這樣看來記憶體泄露實際上不存在。那是什麼原因導致應用啟動時 virtual memory 的使用有那麼大的數值呢?

無奈之後我開始關注virtual memory 這個值得意義,哇,問題出在這裡,它的意義並不是我們想當然的那樣,大相徑庭!

virtual memory 在top命令的manpage是這樣解釋的:

o: VIRT  --  Virtual Image (kb)      The  total  amount  of  virtual  memory  used  by the task.  It      includes all code, data and shared libraries  plus  pages  that      have been swapped out.      VIRT = SWAP + RES.

就是說 virtual memory 不但是包括了代碼資料還包括了共用庫(對於java來說就是jar檔案了),共用庫不但包括正在使用的還包括了已經在SWAP中的。已經在SWAP中的其實就不是在記憶體中了,什麼意思呢,就是說virtual memory 叫做虛擬記憶體,其實這個數值的一部分並不是physic的記憶體,而是磁碟空間。

更近一步解釋:virtual memory 是所有處在virtual memory map 中的資料容量之和,一般來說沒什麼意義。

舉個例子說吧:比如一個程式classpath中引用了10M的jar包,在程式中用到了十個10M的檔案那麼這個程式啟動的時候 virtual memory會是多少呢?

程式本身的code + 程式本身的data + 10m(jars) + 10*10m(檔案) + jre佔用的空間, 這已經是個很大的數字了,但是實際上在程式啟動時並不會將所有的都載入,即便載入了也很快會被swap出去, virtual memory 的數值其實就是個數字,實際中的耗費跟它沒有任何關係。

所以在監控程式中使用virtual memory沒有任何意義是錯誤的,那哪個數值表示實際使用的記憶體呢?

resident memory: the number of pages that are currently resident in RAM

它才是比較靠譜的記憶體使用量值。

介紹一片文章,講這個講的太透了:

什麼是virtual memory

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.