自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

容器中的JVM資源該如何被安全的限制?

云計(jì)算 虛擬化
Java與Docker的結(jié)合,雖然更好的解決了application的封裝問題。但也存在著不兼容,比如Java并不能自動(dòng)的發(fā)現(xiàn)Docker設(shè)置的內(nèi)存限制,CPU限制。

 [[254653]]

前言

Java與Docker的結(jié)合,雖然更好的解決了application的封裝問題。但也存在著不兼容,比如Java并不能自動(dòng)的發(fā)現(xiàn)Docker設(shè)置的內(nèi)存限制,CPU限制。

這將導(dǎo)致JVM不能穩(wěn)定服務(wù)業(yè)務(wù)!容器會(huì)殺死你JVM進(jìn)程,而健康檢查又將拉起你的JVM進(jìn)程,進(jìn)而導(dǎo)致你監(jiān)控你的pod一天重啟次數(shù)甚至能達(dá)到幾百次。

我們希望當(dāng)Java進(jìn)程運(yùn)行在容器中時(shí),java能夠自動(dòng)識(shí)別到容器限制,獲取到正確的內(nèi)存和CPU信息,而不用每次都需要在kubernetes的yaml描述文件中顯示的配置完容器,還需要配置JVM參數(shù)。

使用JVM MaxRAM參數(shù)或者解鎖實(shí)驗(yàn)特性的JVM參數(shù),升級(jí)JDK到10+,我們可以解決這個(gè)問題(也許吧~.~)。

首先Docker容器本質(zhì)是是宿主機(jī)上的一個(gè)進(jìn)程,它與宿主機(jī)共享一個(gè)/proc目錄,也就是說我們在容器內(nèi)看到的/proc/meminfo,/proc/cpuinfo 與直接在宿主機(jī)上看到的一致,如下。

Host

  1. cat /proc/meminfo  
  2. MemTotal: 197869260 kB 
  3. MemFree: 3698100 kB 
  4. MemAvailable: 62230260 kB 

容器

  1. docker run -it --rm alpine cat /proc/meminfo 
  2. MemTotal: 197869260 kB 
  3. MemFree: 3677800 kB 
  4. MemAvailable: 62210088 kB 

那么Java是如何獲取到Host的內(nèi)存信息的呢?沒錯(cuò)就是通過/proc/meminfo來獲取到的。

默認(rèn)情況下,JVM的Max Heap Size是系統(tǒng)內(nèi)存的1/4,假如我們系統(tǒng)是8G,那么JVM將的默認(rèn)Heap≈2G。

Docker通過CGroups完成的是對(duì)內(nèi)存的限制,而/proc目錄是已只讀形式掛載到容器中的,由于默認(rèn)情況下Java 壓根就看不見CGroups的限制的內(nèi)存大小,而默認(rèn)使用/proc/meminfo中的信息作為內(nèi)存信息進(jìn)行啟動(dòng), 這種不兼容情況會(huì)導(dǎo)致,如果容器分配的內(nèi)存小于JVM的內(nèi)存,JVM進(jìn)程會(huì)被理解殺死。

內(nèi)存限制不兼容

我們首先來看一組測試,這里我們采用一臺(tái)內(nèi)存為188G的物理機(jī)。

  1. #free -g total used free shared buff/cache available 
  2. Mem: 188 122 1 0 64 64 

以下的測試中,我們將包含openjdk的hotspot虛擬機(jī),IBM的openj9虛擬機(jī)。

以下測試中,我們把正確識(shí)別到限制的jdk,稱之為安全(即不會(huì)超出容器限制不會(huì)被kill),反之稱之為危險(xiǎn)。

測試用例1(OPENJDK)

這一組測試我們使用***的openjdk8-12,給容器限制內(nèi)存為4G,看JDK默認(rèn)參數(shù)下的***堆為多少?看看我們默認(rèn)參數(shù)下多少版本的JDK是安全的

命令如下,如果你也想試試看,可以用一下命令。

  1. docker run -m 4GB --rm openjdk:8-jre-slim java -XshowSettings:vm -version 
  2. docker run -m 4GB --rm openjdk:9-jre-slim java -XshowSettings:vm -version 
  3. docker run -m 4GB --rm openjdk:10-jre-slim java -XshowSettings:vm -version 
  4. docker run -m 4GB --rm openjdk:11-jre-slim java -XshowSettings:vm -version 
  5. docker run -m 4GB --rm openjdk:12 java -XshowSettings:vm -version 

OpenJDK8(并沒有識(shí)別容器限制,26.67G) 危險(xiǎn)

  1. [root@xiaoke-test ~]# docker run -m 4GB --rm openjdk:8-jre-slim java -XshowSettings:vm -version 
  2. VM settings: 
  3.  Max. Heap Size (Estimated): 26.67G 
  4.  Ergonomics Machine Class: server 
  5.  Using VM: OpenJDK 64-Bit Server VM 
  6. openjdk version "1.8.0_181" 
  7. OpenJDK Runtime Environment (build 1.8.0_181-8u181-b13-2~deb9u1-b13) 
  8. OpenJDK 64-Bit Server VM (build 25.181-b13, mixed mode) 

OpenJDK8 -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap (正確的識(shí)別容器限制,910.50M)安全

  1. [root@xiaoke-test ~]# docker run -m 4GB --rm openjdk:8-jre-slim java -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XshowSettings:vm -version 
  2. VM settings: 
  3.  Max. Heap Size (Estimated): 910.50M 
  4.  Ergonomics Machine Class: server 
  5.  Using VM: OpenJDK 64-Bit Server VM 
  6. openjdk version "1.8.0_181" 
  7. OpenJDK Runtime Environment (build 1.8.0_181-8u181-b13-2~deb9u1-b13) 
  8. OpenJDK 64-Bit Server VM (build 25.181-b13, mixed mode) 

OpenJDK 9(并沒有識(shí)別容器限制,26.67G)危險(xiǎn)

  1. [root@xiaoke-test ~]# docker run -m 4GB --rm openjdk:9-jre-slim java -XshowSettings:vm -version 
  2. VM settings: 
  3.  Max. Heap Size (Estimated): 29.97G 
  4.  Using VM: OpenJDK 64-Bit Server VM 
  5. openjdk version "9.0.4" 
  6. OpenJDK Runtime Environment (build 9.0.4+12-Debian-4) 
  7. OpenJDK 64-Bit Server VM (build 9.0.4+12-Debian-4, mixed mode) 

OpenJDK 9 -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap (正確的識(shí)別容器限制,1G)安全

  1. [root@xiaoke-test ~]# docker run -m 4GB --rm openjdk:9-jre-slim java -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XshowSettings:vm -version 
  2. VM settings: 
  3.  Max. Heap Size (Estimated): 1.00G 
  4.  Using VM: OpenJDK 64-Bit Server VM 
  5. openjdk version "9.0.4" 
  6. OpenJDK Runtime Environment (build 9.0.4+12-Debian-4) 
  7. OpenJDK 64-Bit Server VM (build 9.0.4+12-Debian-4, mixed mode) 

OpenJDK 10(正確的識(shí)別容器限制,1G)安全

  1. [root@xiaoke-test ~]# docker run -m 32GB --rm openjdk:10-jre-slim java -XshowSettings:vm -XX:MaxRAMFraction=1 -version 
  2. VM settings: 
  3.  Max. Heap Size (Estimated): 1.00G 
  4.  Using VM: OpenJDK 64-Bit Server VM 
  5. openjdk version "10.0.2" 2018-07-17 
  6. OpenJDK Runtime Environment (build 10.0.2+13-Debian-2) 
  7. OpenJDK 64-Bit Server VM (build 10.0.2+13-Debian-2, mixed mode) 

OpenJDK 11(正確的識(shí)別容器限制,1G)安全

  1. [root@xiaoke-test ~]# docker run -m 4GB --rm openjdk:11-jre-slim java -XshowSettings:vm -version 
  2. VM settings: 
  3.  Max. Heap Size (Estimated): 1.00G 
  4.  Using VM: OpenJDK 64-Bit Server VM 
  5. openjdk version "11.0.1" 2018-10-16 
  6. OpenJDK Runtime Environment (build 11.0.1+13-Debian-3) 
  7. OpenJDK 64-Bit Server VM (build 11.0.1+13-Debian-3, mixed mode, sharing) 

OpenJDK 12(正確的識(shí)別容器限制,1G)安全

  1. [root@xiaoke-test ~]# docker run -m 4GB --rm openjdk:12 java -XshowSettings:vm -version 
  2. VM settings: 
  3.  Max. Heap Size (Estimated): 1.00G 
  4.  Using VM: OpenJDK 64-Bit Server VM 
  5. openjdk version "12-ea" 2019-03-19 
  6. OpenJDK Runtime Environment (build 12-ea+23) 
  7. OpenJDK 64-Bit Server VM (build 12-ea+23, mixed mode, sharing) 

測試用例2(IBMOPENJ9)

  1. docker run -m 4GB --rm adoptopenjdk/openjdk8-openj9:alpine-slim java -XshowSettings:vm -version 
  2. docker run -m 4GB --rm adoptopenjdk/openjdk9-openj9:alpine-slim java -XshowSettings:vm -version 
  3. docker run -m 4GB --rm adoptopenjdk/openjdk10-openj9:alpine-slim java -XshowSettings:vm -version 
  4. docker run -m 4GB --rm adoptopenjdk/openjdk11-openj9:alpine-slim java -XshowSettings:vm -version 

openjdk8-openj9 (正確的識(shí)別容器限制,3G)安全

  1. [root@xiaoke-test ~]# docker run -m 4GB --rm adoptopenjdk/openjdk8-openj9:alpine-slim java -XshowSettings:vm -version 
  2. VM settings: 
  3.  Max. Heap Size (Estimated): 3.00G 
  4.  Ergonomics Machine Class: server 
  5.  Using VM: Eclipse OpenJ9 VM 
  6. openjdk version "1.8.0_192" 
  7. OpenJDK Runtime Environment (build 1.8.0_192-b12_openj9) 
  8. Eclipse OpenJ9 VM (build openj9-0.11.0, JRE 1.8.0 Linux amd64-64-Bit Compressed References 20181107_95 (JIT enabled, AOT enabled) 
  9. OpenJ9 - 090ff9dcd 
  10. OMR - ea548a66 
  11. JCL - b5a3affe73 based on jdk8u192-b12) 

openjdk9-openj9 (正確的識(shí)別容器限制,3G)安全

  1. [root@xiaoke-test ~]# docker run -m 4GB --rm adoptopenjdk/openjdk9-openj9:alpine-slim java -XshowSettings:vm -version 
  2. VM settings: 
  3.  Max. Heap Size (Estimated): 3.00G 
  4.  Using VM: Eclipse OpenJ9 VM 
  5. openjdk version "9.0.4-adoptopenjdk" 
  6. OpenJDK Runtime Environment (build 9.0.4-adoptopenjdk+12) 
  7. Eclipse OpenJ9 VM (build openj9-0.9.0, JRE 9 Linux amd64-64-Bit Compressed References 20180814_248 (JIT enabled, AOT enabled) 
  8. OpenJ9 - 24e53631 
  9. OMR - fad6bf6e 
  10. JCL - feec4d2ae based on jdk-9.0.4+12) 

openjdk10-openj9 (正確的識(shí)別容器限制,3G)安全

  1. [root@xiaoke-test ~]# docker run -m 4GB --rm adoptopenjdk/openjdk10-openj9:alpine-slim java -XshowSettings:vm -version 
  2. VM settings: 
  3.  Max. Heap Size (Estimated): 3.00G 
  4.  Using VM: Eclipse OpenJ9 VM 
  5. openjdk version "10.0.2-adoptopenjdk" 2018-07-17 
  6. OpenJDK Runtime Environment (build 10.0.2-adoptopenjdk+13) 
  7. Eclipse OpenJ9 VM (build openj9-0.9.0, JRE 10 Linux amd64-64-Bit Compressed References 20180813_102 (JIT enabled, AOT enabled) 
  8. OpenJ9 - 24e53631 
  9. OMR - fad6bf6e 
  10. JCL - 7db90eda56 based on jdk-10.0.2+13) 

openjdk11-openj9(正確的識(shí)別容器限制,3G)安全

  1. [root@xiaoke-test ~]# docker run -m 4GB --rm adoptopenjdk/openjdk11-openj9:alpine-slim java -XshowSettings:vm -version 
  2. VM settings: 
  3.  Max. Heap Size (Estimated): 3.00G 
  4.  Using VM: Eclipse OpenJ9 VM 
  5. openjdk version "11.0.1" 2018-10-16 
  6. OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.1+13) 
  7. Eclipse OpenJ9 VM AdoptOpenJDK (build openj9-0.11.0, JRE 11 Linux amd64-64-Bit Compressed References 20181020_70 (JIT enabled, AOT enabled) 
  8. OpenJ9 - 090ff9dc 
  9. OMR - ea548a66 
  10. JCL - f62696f378 based on jdk-11.0.1+13) 

分析

分析之前我們先了解這么一個(gè)情況:

JavaMemory (MaxRAM) = 元數(shù)據(jù)+線程+代碼緩存+OffHeap+Heap...

一般我們都只配置Heap即使用-Xmx來指定JVM可使用的***堆。而JVM默認(rèn)會(huì)使用它獲取到的***內(nèi)存的1/4作為堆的原因也是如此。

安全性(即不會(huì)超過容器限制被容器kill)

OpenJdk

OpenJdk8-12,都能保證這個(gè)安全性的特點(diǎn)(8和9需要特殊參數(shù),-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap)。

OpenJ9

2.IbmOpenJ9所有的版本都能識(shí)別到容器限制。

資源利用率

OpenJdk

自動(dòng)識(shí)別到容器限制后,OpenJdk把***堆設(shè)置為了大概容器內(nèi)存的1/4,對(duì)內(nèi)存的浪費(fèi)不可謂不大。

當(dāng)然可以配合另一個(gè)JVM參數(shù)來配置***堆。-XX:MaxRAMFraction=int。下面是我整理的一個(gè)常見內(nèi)存設(shè)置的表格, 從中我們可以看到似乎JVM默認(rèn)的***堆的取值為MaxRAMFraction=4,隨著內(nèi)存的增加,堆的閑置空間越來越大,在16G容器內(nèi)存時(shí),java堆只有不到4G。

  1. MaxRAMFraction取值 堆占比 容器內(nèi)存=1G 容器內(nèi)存=2G 容器內(nèi)存=4G 容器內(nèi)存=8G 容器內(nèi)存=16G 
  2. 1 ≈90% 910.50M 1.78G 3.56G 7.11G 14.22G 
  3. 2 ≈50% 455.50M 910.50M 1.78G 3.56G 7.11G 
  4. 3 ≈33% 304.00M 608.00M 1.19G 2.37G 4.74G 
  5. 4 ≈25% 228.00M 455.50M 910.50M 1.78G 3.56G 

OpenJ9

關(guān)于OpenJ9的的詳細(xì)介紹你可以從這里了解更多。 對(duì)于內(nèi)存利用率OpenJ9的策略是優(yōu)于OpenJdk的。以下是OpenJ9的策略表格

  1. 容器內(nèi)存<size> ***Java堆大小 
  2. 小于1 GB 50%<size
  3. 1 GB - 2 GB <size> - 512 MB 
  4. 大于2 GB 大于2 GB 

結(jié)論

注意:這里我們說的是容器內(nèi)存限制,和物理機(jī)內(nèi)存不同,

自動(dòng)檔

如果你想要的是,不顯示的指定-Xmx,讓Java進(jìn)程自動(dòng)的發(fā)現(xiàn)容器限制。

1.如果你想要的是jvm進(jìn)程在容器中安全穩(wěn)定的運(yùn)行,不被容器kill,并且你的JDK版本小于10(大于等于JDK10的版本不需要設(shè)置,參考前面的測試) 你需要額外設(shè)置JVM參數(shù)-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap,即可保證你的Java進(jìn)程不會(huì)因?yàn)閮?nèi)存問題被容器Kill。 當(dāng)然這個(gè)方式使用起來簡單,可靠,缺點(diǎn)也很明顯,資源利用率過低(參考前面的表格MaxRAMFraction=4)。

2.如果想在基礎(chǔ)上我還想提高一些內(nèi)存資源利用率,并且容器內(nèi)存為1 GB - 4 GB,我建議你設(shè)置-XX:MaxRAMFraction=2,在大于8G的可以嘗試設(shè)置-XX:MaxRAMFraction=1(參考上表格)。

手動(dòng)擋

如果你想要的是手動(dòng)擋的體驗(yàn),更加進(jìn)一步的利用內(nèi)存資源,那么你可能需要回到手動(dòng)配置時(shí)代-Xmx。 手動(dòng)擋部分,請可以完全忽略上面我的BB。

1.上面的我們說到了自動(dòng)擋的配置,用起來很簡單很舒服,自動(dòng)發(fā)現(xiàn)容器限制,無需擔(dān)心和思考去配置-Xmx。

2.比如你有內(nèi)存1G那么我建議你的-Xmx750M,2G建議配置-Xmx1700M,4G建議配置-Xmx3500-3700M,8G建議設(shè)置-Xmx7500-7600M, 總之就是至少保留300M以上的內(nèi)存留給JVM的其他內(nèi)存。如果堆特別大,可以預(yù)留到1G甚至2G。

3.手動(dòng)擋用起來就沒有那么舒服了,當(dāng)然資源利用率相對(duì)而言就更高了。

責(zé)任編輯:武曉燕 來源: 今日頭條
相關(guān)推薦

2020-07-31 07:00:00

Kubernetes容器Linux

2021-03-05 00:06:12

Docker容器內(nèi)存

2024-04-07 00:00:00

Linux控制資源

2020-06-20 14:15:53

信息安全數(shù)據(jù)技術(shù)

2022-03-24 08:04:50

Kubernetes資源限制

2023-07-29 22:11:58

Spring容器Component

2023-10-24 07:25:10

容器資源云分級(jí)

2009-07-16 14:28:08

Windows EmbIE安全限制

2015-09-30 10:34:39

容器永久性存儲(chǔ)Docker

2011-08-12 13:19:27

2009-10-20 14:37:41

被就業(yè)NIIT培訓(xùn)

2018-03-15 06:46:55

2020-01-15 11:01:01

端點(diǎn)安全端點(diǎn)防護(hù)EDR

2021-09-18 14:39:01

人工智能數(shù)據(jù)安全隱私

2019-08-21 17:10:13

安全技術(shù)網(wǎng)絡(luò)安全網(wǎng)站

2021-11-26 00:05:56

RabbitMQVirtualHostWeb

2020-04-26 09:44:04

微服務(wù)容器架構(gòu)

2022-07-27 19:27:47

CPU資源內(nèi)存

2018-07-24 16:20:50

WindowsWindows 10帶寬

2012-08-27 09:10:05

JVMJava
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)