短短几年內,容器就改變了軟件行業的面貌。也許您已經到了在容器中運行Java的地步。那很棒!不幸的是,關於容器化Java應用程序的CPU和內存使用率,還有一些事情要注意,我將在下面概述。安全
本文假定整體上熟悉Java和容器。若是您須要更多背景知識,請查看部分(或所有)參考資料。性能
若是有一個關於在容器中運行Java的關鍵聲明,則爲如下內容:spa
不要爲在容器中運行的任何JAVA程序手動設置JVM堆空間。相反的是,設置容器限制。code
爲何?進程
設置容器內存(和CPU)限制。僅依靠資源請求(軟限制)是不夠的。軟限制很是適合幫助調度程序,可是設置硬限制可使Docker(或您使用的任何容器運行時)分配指定的資源給容器自己,而再也不分配更多資源。這也將容許Java(從Java 8u191開始默認爲「容器感知」)根據放置在容器自己上的資源限制(而不是容器正在運行的節點)正確分配內存。內存
[Min | Max | Initial] RAMPercentage
參數在較新的Java版本中,引入瞭如下JVM參數(並將其反向移植到Java 8u191)。資源
-XX:MinRAMPercentage
-XX:MaxRAMPercentage
-XX:InitialRAMPercentage
我不會詳細介紹它們是如何工做的,可是關鍵要點在於它們能夠用於微調JVM堆大小,而無需直接設置堆大小。也就是說,容器仍然能夠依靠施加在其上的限制。it
那麼使用什麼正確的值呢?答案是-「取決於」……尤爲是對容器施加的限制。容器
默認狀況下,JVM堆獲取容器內存的25%。您能夠調整初始/最小/最大堆參數來更改此…例如設置-XX:MaxRAMPercentage = 50將容許JVM爲堆消耗50%的容器內存,而不是默認的25%。何時安全,很大程度上取決於容器必須使用多少內存以及容器中正在運行哪些進程。擴展
例如,若是您的容器正在運行一個Java進程,併爲其分配了4 GB的RAM,而且您設置了-XX:MaxRAMPercentage = 50
,則JVM堆將得到2 GB。這與一般會得到的1 GB默認值相反。在這種狀況下,幾乎能夠確定50%是絕對安全的,甚至是最佳的,由於許多可用RAM可能未獲得充分利用。可是,假設同一容器僅分配了512 MB RAM。如今設置-XX:MaxRAMPercentage = 50
將爲堆提供256 MB的RAM,而僅將其他256 MB留給整個容器的其他部分。該內存將須要由容器中運行的全部其餘進程以及JVM Metaspace / PermGen等分配共享。在這種狀況下,也許50%不太安全。
所以,我提一下幾點建議:
這超出了本文的範圍,但請放心,也能夠對此進行調整,但可能不該該這樣作。默認的JVM行爲適用於大多數用例。若是您發現本身試圖解決一個晦澀的內存問題,那麼多是時候考慮擺弄JVM內存這個有些深奧的領域了,可是不然我將避免直接作任何事情。
這裏沒什麼可作的。從Java 8u191開始,JVM默認狀況下是「容器感知」的,而且能夠正確解釋CPU份額分配。儘管有一些細節值得咱們理解,因此除了在這裏概述以外,我將指導您閱讀這篇出色的文章,詳細說明全部這些。
現代Java很是適合在容器環境中運行,可是每一個人都應該知道一些不太明顯的細節,以確保他們從應用程序中得到最佳性能。我但願這裏提供的信息以及出色的參考資料能夠幫助您實現這一目標。