在 docker中使用java的內存情況


在docker中使用java的內存情況

96 
LOC_Thomas 
2016.12.16 17:52* 字數 807 閱讀 2077評論 0

前言

微服務和docker的結合應該是現在服務端的主流技術,隨着springboot的出現,有很多公司已經把微服務遷移到了docker容器中,我們也不甘寂寞,也嘗試了一把新技術,把以前的整體服務進行拆分以后,也全部上到了docker容器中。

問題

很久之前,業務部門利用springboot開發好一個app以后,就可以通過java -jar 的命令把程序丟給docker,然后在容器中啟動起來,也不管到底系統給這個應用分配了多少內存。

后來由於java默認使用的內存是docker實體機器1/4的內存,導致部署了很多應用以后,經常出現內存不足的情況,然后公司要求應用在啟動的時候通過jvm的啟動參數來限制java使用的內存來緩解內存消耗過快的問題。

再后來,我們的docker平台進行了升級, 有了可以讓應用限制cpu個數和mem大小的參數設置,后面應用方把app的 -Xmx和docker的內存大小設置成同樣大小, 比如2g。后面發現跑了一段時間以后,應用經常出現oom的情況,而被殺掉。

因為java使用的內存不僅僅是 -Xmx設置的大小, -Xmx設置的大小只是java進程堆的最大占用內存,

原因

為什么會出現上面這個問題呢?通過監控系統可以知道,docker獲得的mem_usage的大小是從外部得到的java進程的內存大小,不僅僅是 -Xmx設置的大小,如果 -Xmx和docker分配的內存一致的話,由於java應用其他的地方還要占用不少的內存,導致還沒有到達 -Xmx的時候就沒有可以用的內存了,所以被docker容器給干掉了,從而出現了oom的情況。

那么java程序啟動的時候需要哪些方面的內存呢?

  1. java程序的堆內存,最大就是 -Xmx設置的這個值
  2. Garbage collection在垃圾回收的時候使用的內存
  3. JIT optimization使用的內存
  4. java程序的Off-heap所使用的內存
  5. java程序的Metaspace所使用的內存
  6. JNI Code所占用的內存
  7. jvm啟動的時候所占用的內存。

如何大體估算java進程使用的內存呢?

Max memory = [-Xmx] + [-XX:MaxPermSize] + number_of_threads * [-Xss]

上面的公式大體得到了內存的占用,但是不是全部占用,網上有一些人做了一些試驗,有兩篇比較好的介紹文章:
https://plumbr.eu/blog/memory-leaks/why-does-my-java-process-consume-more-memory-than-xmx

http://trustmeiamadeveloper.com/2016/03/18/where-is-my-memory-java/

所以猜測在設置jvm啟動參數的時候 -Xmx的這個值一般要小於docker限制內存數,個人覺得 -Xmx:docker的比例為 4/5 - 3/4

目前正在試驗和觀察,這里僅僅保存一下記錄,以免忘記。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM