<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          啟動(dòng)Spring Boot時(shí),如果不設(shè)置內(nèi)存參數(shù)會(huì)如何?

          共 4539字,需瀏覽 10分鐘

           ·

          2021-04-03 20:59

          前言

          最近正在進(jìn)行從Spring Boot往Spring Cloud上改造升級(jí)。之前部署的應(yīng)用程序比較少,還沒什么問題。當(dāng)Spring Cloud項(xiàng)目逐步新增之后,問題就爆發(fā)了,服務(wù)器內(nèi)存不夠用了。而現(xiàn)有的用戶體量也沒必要對(duì)服務(wù)器再次進(jìn)行升級(jí),于是就開始著手Spring Boot啟動(dòng)時(shí)JVM內(nèi)存配置的優(yōu)化。

          服務(wù)現(xiàn)狀

          由于之前服務(wù)比較少,服務(wù)器資源充足,許多服務(wù)啟動(dòng)時(shí)都未添加JVM參數(shù)(遺留問題)。結(jié)果就是每個(gè)服務(wù)啟動(dòng)都占用了1.5G-2G的內(nèi)存,有些服務(wù)的體量根本用不了這么多。那么,在Spring Boot中如果未設(shè)置JVM內(nèi)存參數(shù)時(shí),JVM內(nèi)存是如何配置的呢?

          JVM默認(rèn)內(nèi)存設(shè)置

          當(dāng)運(yùn)行一個(gè)Spring Boot項(xiàng)目時(shí),如果未設(shè)置JVM內(nèi)存參數(shù),Spring Boot默認(rèn)會(huì)采用JVM自身默認(rèn)的配置策略。在資源比較充足的情況下,開發(fā)者倒是不太用關(guān)心內(nèi)存的設(shè)置。但一旦涉及到資源不足,JVM優(yōu)化,那么就需要了解默認(rèn)的JVM內(nèi)存配置策略。

          關(guān)于JVM內(nèi)存最常見的設(shè)置為初始堆大小(-Xms)和最大堆內(nèi)存(-Xmx)。很多人懶得去設(shè)置,而是采用JVM的默認(rèn)值。特別是在開發(fā)環(huán)境下,如果啟動(dòng)的微服務(wù)比較多,內(nèi)存會(huì)被撐爆。

          而JVM默認(rèn)內(nèi)存配置策略分兩種場(chǎng)景,大內(nèi)存空間場(chǎng)景和小內(nèi)存空間場(chǎng)景(小于192M)。

          以4GB內(nèi)存為例,初始堆內(nèi)存大小和最大堆內(nèi)存大小如下圖:

          默認(rèn)情況下,最大堆內(nèi)存占用物理內(nèi)存的1/4,如果應(yīng)用程序超過該上限,則會(huì)拋出OutOfMemoryError異常。初始堆內(nèi)存大小為物理內(nèi)存的1/64。

          如果應(yīng)用程序運(yùn)行在手機(jī)上或物理內(nèi)存小于192M時(shí),JVM默認(rèn)的初始堆內(nèi)存大小和最大堆內(nèi)存大小如下圖:

          最大堆內(nèi)存為物理內(nèi)存的1/2,初始堆內(nèi)存大小為物理內(nèi)存的1/64,但當(dāng)初始堆內(nèi)存最小為8MB,則為8MB。

          默認(rèn)空余堆內(nèi)存小于40%時(shí),JVM就會(huì)增大堆直到-Xmx的最大限制;空余堆內(nèi)存大于70%時(shí),JVM會(huì)減少堆到 -Xms的最小限制。因此,服務(wù)器一般設(shè)置-Xms、-Xmx相等以避免在每次GC后調(diào)整堆的大小。對(duì)象的堆內(nèi)存由稱為垃圾回收器的自動(dòng)內(nèi)存管理系統(tǒng)回收。

          其中最大堆內(nèi)存是JVM使用內(nèi)存的上限,實(shí)際運(yùn)行過程中使用多少便是多少。默認(rèn),分配給年輕代的最大空間量是堆總大小的三分之一。

          針對(duì)最開始的問題,如果每個(gè)程序都按照默認(rèn)配置啟動(dòng),一臺(tái)服務(wù)器上部署多個(gè)應(yīng)用時(shí),就會(huì)出現(xiàn)內(nèi)存吃緊的情況,造成一定的浪費(fèi)。最簡(jiǎn)單的操作就是在執(zhí)行java -jar啟動(dòng)時(shí)添加上對(duì)應(yīng)的jvm內(nèi)存設(shè)置參數(shù)。

          java -Xms64m -Xmx128m -jar xxx.jar

          切記參數(shù)要防止-jar參數(shù)之前。否則會(huì)被當(dāng)做系統(tǒng)參數(shù)而無(wú)效。

          當(dāng)然在排查JVM的使用情況時(shí),還會(huì)用到以下相關(guān)操作。

          查看系統(tǒng)默認(rèn)內(nèi)存設(shè)置

          通過上面的描述我們可以看到,不同的系統(tǒng)配置,JVM使用的內(nèi)存是不同的。我們可以通過Java命令自帶的功能來(lái)查看默認(rèn)的內(nèi)存設(shè)置。

          在Linux操作系統(tǒng)下,輸入如下命令:

          java -XX:+PrintFlagsFinal -version | grep HeapSize

          在Windows操作系統(tǒng)下,輸入如下命令:

          java -XX:+PrintFlagsFinal -version | findstr HeapSize

          查看運(yùn)行時(shí)內(nèi)存情況

          當(dāng)應(yīng)用程序運(yùn)行時(shí),如果我們想查看程序的運(yùn)行情況,可通過以下幾種方式來(lái)查詢不同維度的數(shù)據(jù)。

          查看正在運(yùn)行的jvm服務(wù)

          可以通過jps命令查看正在運(yùn)行的jvm服務(wù)。

          appledeMacBook-Pro:~ apple$ jps51972 EurekaApplication51973 Launcher51976 Jps

          其中前面的數(shù)字為進(jìn)程號(hào)。

          查看某進(jìn)程的JVM情況

          可以使用jstat命令查詢具體進(jìn)程的GC情況。

          appledeMacBook-Pro:~ apple$ jstat -gc 51972 5000 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT14336.0 14336.0  0.0   14312.7 145920.0 100055.3  175104.0   17500.2   52136.0 48999.3 7600.0 6958.7      9    0.058   2      0.050    0.10714336.0 14336.0  0.0   14312.7 145920.0 100055.3  175104.0   17500.2   52136.0 48999.3 7600.0 6958.7      9    0.058   2      0.050    0.10714336.0 14336.0  0.0   14312.7 145920.0 100055.3  175104.0   17500.2   52136.0 48999.3 7600.0 6958.7      9    0.058   2      0.050    0.107


          其中51972是進(jìn)程號(hào),5000為刷新時(shí)間。

          對(duì)應(yīng)數(shù)據(jù)項(xiàng)的含義:

          S0C:年輕代中第一個(gè)survivor(幸存區(qū))的容量 (字節(jié)) 

          S1C:年輕代中第二個(gè)survivor(幸存區(qū))的容量 (字節(jié)) 

          S0U:年輕代中第一個(gè)survivor(幸存區(qū))目前已使用空間 (字節(jié)) 

          S1U:年輕代中第二個(gè)survivor(幸存區(qū))目前已使用空間 (字節(jié)) 

          EC:年輕代中Eden(伊甸園)的容量 (字節(jié)) 

          EU:年輕代中Eden(伊甸園)目前已使用空間 (字節(jié)) 

          OC:Old代的容量 (字節(jié)) 

          OU:Old代目前已使用空間 (字節(jié))

          YGC:從應(yīng)用程序啟動(dòng)到采樣時(shí)年輕代中g(shù)c次數(shù) 

          YGCT:從應(yīng)用程序啟動(dòng)到采樣時(shí)年輕代中g(shù)c所用時(shí)間(s) 

          FGC:從應(yīng)用程序啟動(dòng)到采樣時(shí)old代(全gc)gc次數(shù) 

          FGCT:從應(yīng)用程序啟動(dòng)到采樣時(shí)old代(全gc)gc所用時(shí)間(s) 

          GCT:從應(yīng)用程序啟動(dòng)到采樣時(shí)gc用的總時(shí)間(s) 


          查看堆棧使用情況

          通過jmap命令來(lái)查看堆棧的使用情況。

          [root@bjb ~]# jmap -heap 10471Attaching to process ID 10471, please wait...Debugger attached successfully.Server compiler detected.JVM version is 25.262-b10
          using thread-local object allocation.Parallel GC with 2 thread(s)
          Heap Configuration: MinHeapFreeRatio = 0 MaxHeapFreeRatio = 100 MaxHeapSize = 2051014656 (1956.0MB) NewSize = 42991616 (41.0MB) MaxNewSize = 683671552 (652.0MB) OldSize = 87031808 (83.0MB) NewRatio = 2 SurvivorRatio = 8 MetaspaceSize = 21807104 (20.796875MB) CompressedClassSpaceSize = 1073741824 (1024.0MB) MaxMetaspaceSize = 17592186044415 MB G1HeapRegionSize = 0 (0.0MB)
          Heap Usage:PS Young GenerationEden Space: capacity = 342360064 (326.5MB) used = 128426952 (122.47748565673828MB) free = 213933112 (204.02251434326172MB) 37.51224675550943% usedFrom Space: capacity = 4194304 (4.0MB) used = 3458288 (3.2980804443359375MB) free = 736016 (0.7019195556640625MB) 82.45201110839844% usedTo Space: capacity = 4194304 (4.0MB) used = 0 (0.0MB) free = 4194304 (4.0MB) 0.0% usedPS Old Generation capacity = 216006656 (206.0MB) used = 86142704 (82.15208435058594MB) free = 129863952 (123.84791564941406MB) 39.879652597371816% used
          22325 interned Strings occupying 2361920 bytes.

          關(guān)于具體參數(shù)就不在這里解釋了。

          小結(jié)

          項(xiàng)目中往往一些被忽視的問題,深究起來(lái),排查起來(lái),反而能串聯(lián)起來(lái)一系列的知識(shí)點(diǎn)和技能,或許這就是深入思考與探索的魅力所在。你在項(xiàng)目的使用過程中是否也遇到類似的問題,是否也深入探究過么?


          往期推薦

          因?yàn)橐淮五礄C(jī),終于搞透了 Kafka 高可用原理!

          作為架構(gòu)師,你知道前后端分離,有什么優(yōu)缺點(diǎn)?

          最常見的10種Java異常問題

          大佬也hashcode方法上翻船了,不小心秀了一把!

          不要再滿屏寫 try...catch 了!這個(gè)更香!



          如果你覺得這篇文章不錯(cuò),那么,下篇通常會(huì)更好。添加微信好友,可備注“加群”(微信號(hào):zhuan2quan)。

          一篇文章就看透技術(shù)本質(zhì)的人,
            和花一輩子都看不清的人,
            注定是截然不同的搬磚生涯。
          ▲ 長(zhǎng)按關(guān)注”程序新視界“,洞察技術(shù)內(nèi)幕
          瀏覽 43
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  无码高清一卡二卡免费视频 | 91九色首页 | 97九色| 自拍偷拍亚州第一 | 太原操逼网站 |