JVM和Docker默認設置中的陷阱

以下是JVM中Docker默認設置之間的一些常見陷阱。

首先,有很多關於JVM和容器意識的文章:

在本文中,我使用Java 11,這意味着垃圾收集器的默認值應該是G1GC! 讓我們看一下默認值,JVM會根據內存大小和提供的CPU自動選擇這些默認值。

基於Docker CPU的默認GC

$ docker run --cpus="2" openjdk:11-jre java -XX:+PrintFlagsFinal -version | grep -E "(MAX|UseSerialGC|UseG1GC|MaxHeapSize)"

   size_t MaxHeapSize   = 5200936960    {product} {ergonomic}

     bool UseG1GC       = true          {product} {ergonomic}

     bool UseSerialGC   = false         {product} {default}

$ docker run --cpus="1" openjdk:11-jre java -XX:+PrintFlagsFinal -version | grep -E "(MAX|UseSerialGC|UseG1GC|MaxHeapSize)"

   size_t MaxHeapSize    = 5200936960     {product} {ergonomic}

     bool UseG1GC        = false          {product} {default}

     bool UseSerialGC    = true           {product} {ergonomic}

 

注意Docker容器中的CPU數量; 垃圾收集器的類型可以完全不同。

基於Docker內存的默認GC

$ docker run -m 2g openjdk:11-jre java -XX:+PrintFlagsFinal -version | grep -E "(MAX|UseSerialGC|UseG1GC|MaxHeapSize)"

   size_t MaxHeapSize     = 536870912      {product} {ergonomic}

     bool UseG1GC         = true           {product} {ergonomic}

     bool UseSerialGC     = false          {product} {default}

$ docker run -m 1g openjdk:11-jre java -XX:+PrintFlagsFinal -version | grep -E "(MAX|UseSerialGC|UseG1GC|MaxHeapSize)"

   size_t MaxHeapSize    = 268435456     {product} {ergonomic}

     bool UseG1GC        = false         {product} {default}

     bool UseSerialGC    = true          {product} {ergonomic}

 

在上面的代碼片段中,JVM根據提供的內存大小自動更改了默認垃圾回收器。

默認堆大小始終是可用內存的1/4!

$ docker run -m 512m openjdk:11-jre java -XX:+PrintFlagsFinal -version | grep -E "(MAX|UseSerialGC|UseG1GC|MaxHeapSize)"

   size_t MaxHeapSize     = 134217728     {product} {ergonomic}

     bool UseG1GC         = false         {product} {default}

     bool UseSerialGC     = true          {product} {ergonomic}

$ docker run -m 256m openjdk:11-jre java -XX:+PrintFlagsFinal -version | grep -E "(MAX|UseSerialGC|UseG1GC|MaxHeapSize)"

   size_t MaxHeapSize     = 132120576      {product} {ergonomic}

     bool UseG1GC         = false          {product} {default}

     bool UseSerialGC     = true           {product} {ergonomic}

 

JVM從一定數量的內存中停止選擇堆大小的1/4,並開始使比率越來越小,以爲的應用程序提供更大的堆內存

爲什麼選擇SerialGC?

$ docker run -m 1g openjdk:11-jre java -XX:+PrintFlagsFinal -version | grep -E "(MAX|UseSerialGC|UseG1GC|MaxHeapSize)"

   size_t MaxHeapSize      = 268435456      {product} {ergonomic}

     bool UseG1GC          = false          {product} {default}

     bool UseSerialGC      = true           {product} {ergonomic}

$ docker run -m 1g openjdk:11-jre java -Xmx700m -XX:+PrintFlagsFinal -version | grep -E "(MAX|UseSerialGC|UseG1GC|MaxHeapSize)"

   size_t MaxHeapSize      = 734003200         {product} {command line}

     bool UseG1GC          = false             {product} {default}

     bool UseSerialGC      = true              {product} {ergonomic}

 

這很奇怪,根據上面的示例,我們仍然應該將G1GC作爲默認值,但是知道我們可以注意到JVM選擇了SerialGC。 一講,總是必須嘗試一下JVM選擇了哪些默認值,並考慮它是否合理並適合 會注意到JVM定義的參數被標記爲符合人體工程學的JVM選項。

> 喜歡這篇文章的可以點個贊,歡迎大家留言評論,記得關注我,每天持續更新技術乾貨、職場趣事、海量面試資料等等

 > 如果你對java技術很感興趣也可以交流學習,共同學習進步。 

> 不要再用"沒有時間“來掩飾自己思想上的懶惰!趁年輕,使勁拼,給未來的自己一個交代


文章寫道這裏,歡迎完善交流。最後奉上近期整理出來的一套完整的java架構思維導圖,分享給大家對照知識點參考學習。有更多JVM、Mysql、Tomcat、Spring Boot、Spring Cloud、Zookeeper、Kafka、RabbitMQ、RockerMQ、Redis、ELK、Git等Java乾貨


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章