JVM和Docker默認設置中的陷阱


 

通過優銳課核心java學習筆記中,我們可以看到,碼了很多專業的相關知識, 分享給大家參考學習。

以下是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干貨


免責聲明!

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



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