日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁 > 科技  > 軟件

Kubernetes 中的 Java 應(yīng)用的內(nèi)存調(diào)優(yōu)

來源: 責(zé)編: 時間:2023-10-18 09:18:41 300觀看
導(dǎo)讀前言在 Kubernetes 環(huán)境中運(yùn)行 Java 應(yīng)用程序雖然很常見,但往往也充滿各種問題,特別是在管理內(nèi)存資源時。在本文中,我們將討論配置應(yīng)用程序以優(yōu)化 Kubernetes 環(huán)境中的內(nèi)存使用并避免內(nèi)存不足問題的一些最佳實(shí)踐。OpenJD

OLH28資訊網(wǎng)——每日最新資訊28at.com

前言

在 Kubernetes 環(huán)境中運(yùn)行 Java 應(yīng)用程序雖然很常見,但往往也充滿各種問題,特別是在管理內(nèi)存資源時。在本文中,我們將討論配置應(yīng)用程序以優(yōu)化 Kubernetes 環(huán)境中的內(nèi)存使用并避免內(nèi)存不足問題的一些最佳實(shí)踐。OLH28資訊網(wǎng)——每日最新資訊28at.com

OpenJDK 17 中的內(nèi)存空間

OpenJDK 17 包含 Java 虛擬機(jī) (JVM) 使用的多個內(nèi)存空間來管理 Java 應(yīng)用程序的內(nèi)存。了解這些不同的內(nèi)存空間可以幫助開發(fā)人員針對 Kubernetes 環(huán)境優(yōu)化其 Java 應(yīng)用程序。OLH28資訊網(wǎng)——每日最新資訊28at.com

圖片OLH28資訊網(wǎng)——每日最新資訊28at.com

Heap Memory-堆內(nèi)存

堆內(nèi)存會在Java運(yùn)行時分配給對象(Object)或者JRE類。每當(dāng)我們創(chuàng)建一個對象的時候,在堆內(nèi)存中就會分配一塊儲存空間給這個對象。Java的垃圾回收機(jī)制就是運(yùn)行在堆內(nèi)存上的,用以釋放那些沒有任何引用指向自身的對象(不可達(dá)的對象。注意Java的垃圾回收也會處理幾個相互引用但沒有任何外部引用的對象)。任何在堆內(nèi)存中分配的對象都有全局訪問權(quán)限,可以從應(yīng)用的任何地方被引用。OLH28資訊網(wǎng)——每日最新資訊28at.com

堆內(nèi)存是存儲Java應(yīng)用程序創(chuàng)建的對象的地方。它是Java應(yīng)用程序最重要的內(nèi)存空間。在 OpenJDK 17 中,默認(rèn)堆大小是根據(jù)可用物理內(nèi)存計(jì)算的,并設(shè)置為可用內(nèi)存的 1/4。OLH28資訊網(wǎng)——每日最新資訊28at.com

Young Generation-年輕代

對象被創(chuàng)建時,內(nèi)存的分配首先發(fā)生在年輕代(大對象可以直接被創(chuàng)建在年老代),大部分的對象在創(chuàng)建后很快就不再使用,因此很快變得不可達(dá),于是被年輕代的GC機(jī)制清理掉(IBM的研究表明,98%的對象都是很快消亡的),這個GC機(jī)制被稱為Minor GC或叫Young GC。注意,Minor GC并不代表年輕代內(nèi)存不足,它事實(shí)上只表示在Eden區(qū)上的GC。OLH28資訊網(wǎng)——每日最新資訊28at.com

年輕代上的內(nèi)存分配是這樣的,年輕代可以分為3個區(qū)域:Eden區(qū)(伊甸園,亞當(dāng)和夏娃偷吃禁果生娃娃的地方,用來表示內(nèi)存首次分配的區(qū)域,再貼切不過)和兩個存活區(qū)(Survivor 0 、Survivor 1)。OLH28資訊網(wǎng)——每日最新資訊28at.com

Old Generation-老一輩

對象如果在年輕代存活了足夠長的時間而沒有被清理掉(即在幾次Young GC后存活了下來),則會被復(fù)制到年老代,年老代的空間一般比年輕代大,能存放更多的對象,在年老代上發(fā)生的GC次數(shù)也比年輕代少。當(dāng)年老代內(nèi)存不足時,將執(zhí)行Major GC,也叫 Full GC。  OLH28資訊網(wǎng)——每日最新資訊28at.com

可以使用-XX:+UseAdaptiveSizePolicy開關(guān)來控制是否采用動態(tài)控制策略,如果動態(tài)控制,則動態(tài)調(diào)整Java堆中各個區(qū)域的大小以及進(jìn)入老年代的年齡。OLH28資訊網(wǎng)——每日最新資訊28at.com

如果對象比較大(比如長字符串或大數(shù)組),Young空間不足,則大對象會直接分配到老年代上(大對象可能觸發(fā)提前GC,應(yīng)少用,更應(yīng)避免使用短命的大對象)。用-XX:PretenureSizeThreshold來控制直接升入老年代的對象大小,大于這個值的對象會直接分配在老年代上。OLH28資訊網(wǎng)——每日最新資訊28at.com

可能存在年老代對象引用新生代對象的情況,如果需要執(zhí)行Young GC,則可能需要查詢整個老年代以確定是否可以清理回收,這顯然是低效的。解決的方法是,年老代中維護(hù)一個512 byte的塊——”card table“,所有老年代對象引用新生代對象的記錄都記錄在這里。Young GC時,只要查這里即可,不用再去查全部老年代,因此性能大大提高。OLH28資訊網(wǎng)——每日最新資訊28at.com

Metaspace-元空間

非堆空間被 JVM 用于存儲元數(shù)據(jù)和類定義。在舊版本的 Java 中,它也稱為永久代 (PermGen)。在 OpenJDK 17 中,PermGen 空間已被新的 Metaspace 取代,其設(shè)計(jì)更加高效和靈活。OLH28資訊網(wǎng)——每日最新資訊28at.com

Code Cache-代碼緩存

簡而言之,JVM Code Cache (代碼緩存)是JVM存儲編譯成本機(jī)代碼的字節(jié)碼的區(qū)域。我們將可執(zhí)行本機(jī)代碼的每個塊稱為nmethod。nmethod可能是一個完整的或內(nèi)聯(lián)的Java方法。OLH28資訊網(wǎng)——每日最新資訊28at.com

即時(JIT)編譯器是代碼緩存區(qū)的最大消費(fèi)者。這就是為什么一些開發(fā)人員將此內(nèi)存稱為JIT代碼緩存。OLH28資訊網(wǎng)——每日最新資訊28at.com

Thread Stack Space-線程堆??臻g

Java程序中,每個線程都有自己的Stack Space(堆棧)。這個Stack Space不是來自Heap的分配。所以Stack Space的大小不會受到-Xmx和-Xms的影響,這2個JVM參數(shù)僅僅是影響Heap的大小。OLH28資訊網(wǎng)——每日最新資訊28at.com

Stack Space用來做方法的遞歸調(diào)用時壓入Stack Frame(棧幀)。所以當(dāng)遞歸調(diào)用太深的時候,就有可能耗盡Stack Space,爆出StackOverflow的錯誤。OLH28資訊網(wǎng)——每日最新資訊28at.com

-Xss128k:設(shè)置每個線程的堆棧大小。JDK5.0以后每個線程堆 棧大小為1M,以前每個線程堆棧大小為256K。根據(jù)應(yīng)用的線程所需內(nèi)存大小進(jìn)行調(diào)整。在相同物理內(nèi)存下,減小這個值能生成更多的線程。但是操作系統(tǒng)對一 個進(jìn)程內(nèi)的線程數(shù)還是有限制的,不能無限生成,經(jīng)驗(yàn)值在3000~5000左右。OLH28資訊網(wǎng)——每日最新資訊28at.com

線程棧的大小是個雙刃劍,如果設(shè)置過小,可能會出現(xiàn)棧溢出,特別是在該線程內(nèi)有遞歸、大的循環(huán)時出現(xiàn)溢出的可能性更大,如果該值設(shè)置過大,就有影響到創(chuàng)建棧的數(shù)量,如果是多線程的應(yīng)用,就會出現(xiàn)內(nèi)存溢出的錯誤。OLH28資訊網(wǎng)——每日最新資訊28at.com

Shared libs-共享庫

Java JVM 中的共享庫空間(也稱為共享類數(shù)據(jù)空間)是用于存儲共享類元數(shù)據(jù)和其他數(shù)據(jù)結(jié)構(gòu)的內(nèi)存空間。該內(nèi)存空間在多個 Java 進(jìn)程之間共享。這允許在同一臺機(jī)器上運(yùn)行的各種 Java 應(yīng)用程序共享類元數(shù)據(jù)和其他數(shù)據(jù)結(jié)構(gòu)的相同副本。 OLH28資訊網(wǎng)——每日最新資訊28at.com

共享庫空間的目的是通過避免同一類元數(shù)據(jù)的重復(fù)副本來減少內(nèi)存使用并提高性能。當(dāng)多個 Java 進(jìn)程使用相同的類元數(shù)據(jù)時,它們可以共享該元數(shù)據(jù)的相同副本,從而減少內(nèi)存使用并縮短應(yīng)用程序的啟動時間。OLH28資訊網(wǎng)——每日最新資訊28at.com

為什么要微調(diào)JVM的內(nèi)存設(shè)置?

JVM 的默認(rèn)行為會給 Kubernetes 帶來很多麻煩。正如我們之前看到的,堆默認(rèn)設(shè)置為可用內(nèi)存的 1/4。由于 JVM 將考慮 pod 可用的最大內(nèi)存(有限制),因此堆的大小可能會比我們想要的大。此外,其他默認(rèn)值將應(yīng)用于其他空間,例如代碼緩存或元空間。 如果從 JVM 的角度來看最大可用內(nèi)存,它將大于提供給 pod 的最大可用內(nèi)存。這將導(dǎo)致應(yīng)用程序出現(xiàn)許多內(nèi)存不足的情況(在 Kubernetes 部分)。OLH28資訊網(wǎng)——每日最新資訊28at.com

避免Java應(yīng)用程序在Kubernetes上出現(xiàn)OOM

大多數(shù)時候,都是為了微調(diào) JVM。由于我們看到 JVM 涉及不同的內(nèi)存空間,因此我們必須為每個空間設(shè)置特定的大小。這將幫助我們更精確地計(jì)算 pod 的內(nèi)存限制。 以下是顯示每個內(nèi)存空間可用選項(xiàng)的架構(gòu):OLH28資訊網(wǎng)——每日最新資訊28at.com

圖片OLH28資訊網(wǎng)——每日最新資訊28at.com

基本公式是:OLH28資訊網(wǎng)——每日最新資訊28at.com

Heap + Metaspace + Code Cache

意思是 :OLH28資訊網(wǎng)——每日最新資訊28at.com

-XmX + -XX:MaxMetaspaceSize + -XX:ReservedCodeCacheSize

由于線程的數(shù)量取決于應(yīng)用程序的上下文,因此建議為此部分添加一些“緩沖”內(nèi)存。默認(rèn)情況下,線程堆棧最大設(shè)置為 1MB。OLH28資訊網(wǎng)——每日最新資訊28at.com

如果想處理來自 JVM 的堆轉(zhuǎn)儲,則需要添加堆的大小作為第二次可用的“額外”內(nèi)存。 最后,設(shè)置 pod 限制的公式為:OLH28資訊網(wǎng)——每日最新資訊28at.com

(-XmX * 2) + -XX:MaxMetaspaceSize + -XX:ReservedCodeCacheSize + SomeBuffer

緩沖區(qū)部分取決于上下文,128 MB 應(yīng)該可以開始。OLH28資訊網(wǎng)——每日最新資訊28at.com

Helm模板配置

既然有了公式,我們就可以使用一些 Helm 模板自動計(jì)算 pod 的請求和限制。為開發(fā)人員提供一個簡單的選項(xiàng)來設(shè)置不同的參數(shù),而無需擔(dān)心 Pods 設(shè)置,這也是一個好的方式。 以下是默認(rèn)值的示例:OLH28資訊網(wǎng)——每日最新資訊28at.com

jvm: garbageCollector: -XX:+UseG1GC # values in Mi memory:   heap: 128   metaspace: 256   compressedClassSpaceSize: 64   nonMethodCodeHeapSize: 5   profiledCodeHeapSize: 48   nonProfiledCodeHeapSize: 48   buffer: 128

使用 Helper 來設(shè)置 JAVA_TOOL_OPTIONS :OLH28資訊網(wǎng)——每日最新資訊28at.com

{{/*JVM customisation*/}}{{- define "chart.javaToolOptions" -}}-Xms{{.Values.jvm.memory.heap}}m -Xmx{{.Values.jvm.memory.heap}}m -XX:MetaspaceSize={{.Values.jvm.memory.metaspace}}m -XX:MaxMetaspaceSize={{.Values.jvm.memory.metaspace}}m -XX:CompressedClassSpaceSize={{.Values.jvm.memory.compressedClassSpaceSize}}m -XX:+TieredCompilation -XX:+SegmentedCodeCache -XX:Nnotallow={{.Values.jvm.memory.nonMethodCodeHeapSize}}m -XX:ProfiledCodeHeapSize={{.Values.jvm.memory.profiledCodeHeapSize}}m -XX:Nnotallow={{.Values.jvm.memory.nonProfiledCodeHeapSize}}m -XX:ReservedCodeCacheSize={{ add .Values.jvm.memory.nonMethodCodeHeapSize .Values.jvm.memory.profiledCodeHeapSize .Values.jvm.memory.nonProfiledCodeHeapSize}}m{{- end -}}

在deployment.yaml文件中使用:OLH28資訊網(wǎng)——每日最新資訊28at.com

- name: {{ include "chart.name" . }}         image: "{{ .Values.container.image.repository }}:{{ .Values.container.image.tag }}"         env:           - name: JAVA_TOOL_OPTIONS             value: {{ include "chart.javaToolOptions" . }}

根據(jù)提供的參數(shù)自動配置內(nèi)存請求和限制:OLH28資訊網(wǎng)——每日最新資訊28at.com

resources:           limits:             memory: {{ add .Values.jvm.memory.heap .Values.jvm.memory.heap .Values.jvm.memory.metaspace .Values.jvm.memory.nonMethodCodeHeapSize .Values.jvm.memory.profiledCodeHeapSize .Values.jvm.memory.nonProfiledCodeHeapSize .Values.jvm.memory.buffer | printf "%dMi"}}             cpu: {{ .Values.container.resources.limits.cpu }}           requests:             memory: {{ add .Values.jvm.memory.heap .Values.jvm.memory.metaspace .Values.jvm.memory.nonMethodCodeHeapSize .Values.jvm.memory.profiledCodeHeapSize .Values.jvm.memory.nonProfiledCodeHeapSize | printf "%dMi"}}             cpu: {{ .Values.container.resources.requests.cpu }}

結(jié)論

通過這一設(shè)置,我們將 Kubernetes 一側(cè)的 "內(nèi)存不足"(Out Of Memory)錯誤數(shù)量降至零?,F(xiàn)在,JVM 會在自己這邊發(fā)生 OOM,并生成堆轉(zhuǎn)儲,幫助開發(fā)人員分析內(nèi)存。我們會發(fā)現(xiàn)是否有一些優(yōu)化需要推進(jìn),或者我們是否需要增加堆大?。ɑ蚱渌麅?nèi)存空間)。OLH28資訊網(wǎng)——每日最新資訊28at.com

通過微調(diào) JVM 內(nèi)存配置,我們打破了惡性循環(huán),即每次 OOM 都意味著為 pod 增加內(nèi)存,以避免未來出現(xiàn)問題。我們能更好地了解每個內(nèi)存空間,以及如何和何時增加它們。OLH28資訊網(wǎng)——每日最新資訊28at.com

圖片OLH28資訊網(wǎng)——每日最新資訊28at.com

每次調(diào)整都需要測試,因此我們建議使用一些工具,例如 Micrometer,來獲得有關(guān) JVM 使用情況的一些指標(biāo)。 而且,最重要的是,我們減少了應(yīng)用程序的內(nèi)存需求,并通過減少內(nèi)存浪費(fèi)事實(shí)上降低了基礎(chǔ)設(shè)施的成本!OLH28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-13840-0.htmlKubernetes 中的 Java 應(yīng)用的內(nèi)存調(diào)優(yōu)

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 用Babel和Nodemon搭建一個功能齊全的Nodejs開發(fā)環(huán)境

下一篇: 利用貝葉斯網(wǎng)絡(luò)預(yù)測醫(yī)院服務(wù)患者數(shù)量

標(biāo)簽:
  • 熱門焦點(diǎn)
Top 主站蜘蛛池模板: 子洲县| 安泽县| 荃湾区| 龙川县| 南溪县| 绥化市| 阜平县| 察雅县| 东至县| 伊宁市| 张家港市| 满洲里市| 乐至县| 武冈市| 崇信县| 图们市| 思南县| 库车县| 滕州市| 漳浦县| 如皋市| 太康县| 安远县| 博白县| 确山县| 兴化市| 西和县| 南召县| 乌拉特前旗| 庆云县| 灯塔市| 瑞丽市| 乡城县| 乌兰察布市| 武夷山市| 宜宾县| 垣曲县| 长葛市| 大厂| 隆尧县| 太康县|