<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>

          億級(jí)流量電商系統(tǒng)JVM模型參數(shù)二次優(yōu)化

          共 2424字,需瀏覽 5分鐘

           ·

          2021-10-25 08:23

          一、億級(jí)流量分析及jvm參數(shù)設(shè)置

          1. 需求分析

          大促在即,擁有億級(jí)流量的電商平臺(tái)開(kāi)發(fā)了一個(gè)訂單系統(tǒng),我們應(yīng)該如何來(lái)預(yù)估其并發(fā)量?如何根據(jù)并發(fā)量來(lái)合理配置JVM參數(shù)呢?

          假設(shè),現(xiàn)在有一個(gè)場(chǎng)景,一個(gè)電商平臺(tái),比如京東,需要承擔(dān)每天上億的流量?,F(xiàn)在開(kāi)發(fā)了一個(gè)訂單系統(tǒng),那么這個(gè)訂單系統(tǒng)每秒的并發(fā)量是多少呢?我們應(yīng)該如何分配其內(nèi)存空間呢?先來(lái)分析一下

          每日億級(jí)流量,平均一個(gè)用戶點(diǎn)擊量在20-30左右,通過(guò)這個(gè)計(jì)算出日活用戶數(shù)約1億/20=500萬(wàn), 看的人多,買的人少,通常下單率不超過(guò)10%,我們按照留存率10%來(lái)計(jì)算,日均訂單約50萬(wàn)單。這是分兩種情況:

          • 一種是普通流量,非特殊節(jié)假日,通常早上、中午、晚上非工作時(shí)間有1個(gè)小時(shí)的時(shí)間集中購(gòu)買。我們按照早上1小時(shí),中午1小時(shí),晚上1小時(shí)來(lái)計(jì)算,也就是3小時(shí)。這樣平均到每秒就是50萬(wàn)/3/3600=46, 也就是及時(shí)并發(fā),通常我們的服務(wù)都是一個(gè)集群,有好幾臺(tái)服務(wù)器承受著幾十并發(fā),應(yīng)該不成問(wèn)題。

          • 另一種是大促流量,比如雙十一,基本流量都集中在雙十一當(dāng)天的投幾分鐘。這時(shí)每秒的并發(fā)量大概在50萬(wàn)/10/60=866,平均每秒并發(fā)量不到1000。這時(shí)服務(wù)集群有3臺(tái)服務(wù)器,沒(méi)太服務(wù)器承受的壓力是400單/s。

          2. 常規(guī)方案及問(wèn)題暴露

          對(duì)于這每秒400但會(huì)產(chǎn)生多大的對(duì)象呢?

          我們假設(shè)訂單對(duì)象的大小是1kb,實(shí)際上訂單對(duì)象的大小和訂單對(duì)象中的字段有關(guān)系,我們假設(shè)是1kb。每秒400單,也就是會(huì)產(chǎn)生400kb的訂單對(duì)象。下單還涉及到其他對(duì)象,比如庫(kù)存,優(yōu)惠券,積分等等,我們將對(duì)象擴(kuò)大20倍, 大約是(400kb*20)/秒. 可能同時(shí)還有其他操作,比如查詢訂單的操作,我們?cè)僦v其擴(kuò)大10倍,大約是80M,也就是每秒產(chǎn)生約80M的對(duì)象,這些對(duì)象在1s后都會(huì)變?yōu)槔?/p>

          對(duì)于一臺(tái)4核8G的服務(wù)器來(lái)說(shuō),通常我們不設(shè)置JVM參數(shù),也可能會(huì)根據(jù)物理機(jī)的8G內(nèi)存來(lái)設(shè)置JVM參數(shù)。如果根據(jù)JVM參數(shù)來(lái)設(shè)置參數(shù)如何設(shè)置呢?

          之前說(shuō)過(guò)開(kāi)啟逃逸分析會(huì)將對(duì)象分配到棧上,我們這里計(jì)算分析的時(shí)候暫且忽略逃逸分析分配到棧上的對(duì)象,因?yàn)檫@部分對(duì)象相對(duì)來(lái)說(shuō)比較少。下面我們來(lái)驗(yàn)證上面的預(yù)估算法是否準(zhǔn)確,會(huì)有什么樣的問(wèn)題呢?

          物理機(jī)有8G,分給os操作系統(tǒng)3G,分給JVM5G,然后JVM中給堆分配3G,元數(shù)據(jù)空間分配512M,線程棧分配1M等等。這是估算,不夠精細(xì),到底分配這么多空間夠不夠呢,會(huì)不會(huì)浪費(fèi)呢?會(huì)產(chǎn)生什么樣的問(wèn)題呢?

          設(shè)置jvm參數(shù)大致如下:
          ?
          -Xms3072M -Xmx3072M -Xss1M -XX:MetaspaceSize=512M -XX:MaxMetaspaceSize=512M
          復(fù)制代碼

          這樣設(shè)置到底行不行呢?有沒(méi)有問(wèn)題呢?我們來(lái)看看運(yùn)行時(shí)數(shù)據(jù)區(qū):

          根據(jù)計(jì)算

          • 整個(gè)堆空間3G

            • Eden區(qū)800M

            • s1/s2各100M

          • 方法區(qū)512M

          • 一個(gè)線程1M

          按照這個(gè)模型來(lái)分析,得到如下結(jié)果:

          1. 大促期間1s產(chǎn)生80M的對(duì)象數(shù)據(jù)。我們知道對(duì)象數(shù)據(jù)都是放在Eden園區(qū),Eden園區(qū)一共800M,那么大約10s就放滿了,放滿了就會(huì)觸發(fā)Minor GC

          2. 觸發(fā)Minor GC的期間,會(huì)Stop The World暫停業(yè)務(wù)線程。在第10s觸發(fā)MinorGC的時(shí)候,前9s的720M數(shù)據(jù)都已經(jīng)變成垃圾了,會(huì)被回收掉,最后1s的80M數(shù)據(jù)由于還有對(duì)象引用,只是暫停了業(yè)務(wù)線程,因此不是垃圾,不能被回收。會(huì)被放入S1區(qū)。

          3. 在Survivor區(qū)有一個(gè)對(duì)象動(dòng)態(tài)年齡判斷機(jī)制。什么是對(duì)象動(dòng)態(tài)年齡判斷機(jī)制呢?

          當(dāng)前放對(duì)象的Survivor區(qū)域里(其中一塊區(qū)域,放對(duì)象的那塊s區(qū)),一批對(duì)象的總大小大于這塊Survivor區(qū)域內(nèi)存大小的50%(-XX:TargetSurvivorRatio可以指定),那么此時(shí)大于等于這批對(duì)象年齡最大值的對(duì)象,就可以直接進(jìn)入老年代了,

          例如:Survivor區(qū)域里現(xiàn)在有一批對(duì)象,年齡1+年齡2+年齡n的多個(gè)年齡對(duì)象總和超過(guò)了Survivor區(qū)域的50%,此時(shí)就會(huì)把年齡n(含)以上的對(duì)象都放入老年代。這個(gè)規(guī)則其實(shí)是希望那些可能是長(zhǎng)期存活的對(duì)象,盡早進(jìn)入老年代。

          對(duì)象動(dòng)態(tài)年齡判斷機(jī)制一般是在minor gc之后觸發(fā)的。

          也就是說(shuō)當(dāng)在Survivor區(qū)經(jīng)過(guò)幾代的回收以后,如果對(duì)象總和大于Survivor區(qū)域的一半,則會(huì)直接放入到老年代。Survivor是100M,第10s的對(duì)象是80M,大于100M,會(huì)直接將這個(gè)對(duì)象放入到老年代。

          1. 老年代一共有2G空間,2G空間執(zhí)行多少次會(huì)滿呢?2G/80M=25次,也就是發(fā)生25次(25秒)Minor GC就會(huì)觸發(fā)一次Full GC。這個(gè)頻率就太高了,通常應(yīng)該要很少觸發(fā)Full GC,起碼也得1個(gè)小時(shí)觸發(fā)一次。而觸發(fā)的原因是因?yàn)槔鴮?duì)象(這些對(duì)象1s后都變成垃圾了),這樣肯定是不行的。我們需要優(yōu)化JVM參數(shù)。

          3. JVM優(yōu)化

          有問(wèn)題有就解決問(wèn)題。問(wèn)題的根本原因是老年代發(fā)生了Full GC,為什么會(huì)發(fā)生Full GC呢?

          之所以80M對(duì)象會(huì)放到了老年代是因?yàn)槊棵氘a(chǎn)生的數(shù)據(jù) 大于 Survivor區(qū)空間的一半。所以,我們可以調(diào)整Survivor區(qū)大小。通常我們不會(huì)修改默認(rèn)的Eden:S1:S2的比例,所以,我們可以考慮從整體擴(kuò)大新生代的內(nèi)存空間。假設(shè)我們擴(kuò)大到2G,讓老年代是1G。

          這時(shí)會(huì)怎么樣呢?

          • Young區(qū)占2G,Eden區(qū)有1.6G, S1、S2各有200M。

          這時(shí)在分析:

          • Eden區(qū)有1.6G,每秒產(chǎn)生80M的對(duì)象放到Eden區(qū),大約1.6G/80=20s放滿。

          • 放滿以后觸發(fā)Minor GC, 此時(shí)前19s的對(duì)象都已經(jīng)成為垃圾被回收,第20s的對(duì)象被轉(zhuǎn)移到S1區(qū)。

          • 此時(shí),S1區(qū)有200M,80

          • 又過(guò)了20s,進(jìn)行第二次Minor GC,這次Eden區(qū)又產(chǎn)生了1.52G的垃圾被回收,之前在S1區(qū)的80M對(duì)象也已經(jīng)變成垃圾被回收。新的80M對(duì)象被放入到S2區(qū)。沒(méi)有進(jìn)入到老年代。

          • 以此類推,第三次,第四次,垃圾對(duì)象不會(huì)再進(jìn)入老年代,因此也不會(huì)在發(fā)生Full GC.

          由此分析,大大降低了Full GC發(fā)生的頻率。

          最終參數(shù)設(shè)置:

          -Xms3072M -Xmx3072M -Xmn2048M -Xss1M -XX:MetaspaceSize=512M -XX:MaxMetaspaceSize=512M 
          ?
          為了更清晰的看到效果,可以打印GC詳細(xì)日志
          -XX:+PrintGCDetails
          復(fù)制代碼

          4. 總結(jié)

          通過(guò)上面的數(shù)據(jù)分析,我們要養(yǎng)成一個(gè)習(xí)慣,做任何事情都是要有理有據(jù),不能是拍腦袋就說(shuō)出來(lái)的。一定要能夠經(jīng)得起驗(yàn)證的。

          二、億級(jí)流量jvm參數(shù)優(yōu)化--使用parNew和CMS垃圾收集器

          1. 需求分析

          上面的參數(shù)設(shè)置,幫我們解決了多次觸發(fā)Full GC的問(wèn)題,通過(guò)調(diào)整參數(shù)以后,我們看出在預(yù)期正常情況下,基本不會(huì)觸發(fā)Full GC。但如果有意外情況呢?比如,我們的一臺(tái)服務(wù)器能夠承受的最大并發(fā)量是400/s,但如果在秒殺的時(shí)候,并發(fā)量超過(guò)了這種情況是在不發(fā)生意外的情況下。假如并發(fā)流量達(dá)到1000,內(nèi)存模型是怎么樣的呢?

          根據(jù)這個(gè)估算模型,正常情況下訂單系統(tǒng)可以承接的訂單并發(fā)量是400單/s,但遇到某一個(gè)大促活動(dòng),很可能并發(fā)量沖到700單/s, 1000單/s,這是一秒產(chǎn)生的垃圾就不是60M了,可能是120M,甚至更多。根據(jù)之前的分析,這時(shí)又會(huì)頻繁的觸發(fā)Full GC了。當(dāng)然了,我們有很多辦法來(lái)控制并發(fā)量,比如限流、擴(kuò)容。但這里我們從JVM的角度來(lái)分析,如何處理這個(gè)問(wèn)題。

          正常情況我們的jvm參數(shù)是如下設(shè)置:

          ‐Xms3072M ‐Xmx3072M ‐Xss1M ‐XX:MetaspaceSize=256M ‐XX:MaxMetaspaceSize=256M ‐XX:SurvivorRatio=8
          復(fù)制代碼

          經(jīng)過(guò)上面的分析,這樣設(shè)置可能會(huì)由于動(dòng)態(tài)對(duì)象年齡判斷原則導(dǎo)致頻繁full gc。于是我們?cè)O(shè)置如下JVM參數(shù),盡量避免觸發(fā)full GC

           ‐Xms3072M ‐Xmx3072M ‐Xmn2048M ‐Xss1M ‐XX:MetaspaceSize=256M ‐XX:MaxMetaspaceSize=256M ‐XX:SurvivorRatio=8
          復(fù)制代碼

          2. JVM優(yōu)化

          這個(gè)原理在上面已經(jīng)說(shuō)過(guò)了,但是如果并發(fā)量從峰值400單/s,一下沖到700~1000單/s。這時(shí)候,很顯然,又會(huì)觸發(fā)Full GC了,因?yàn)閮?nèi)存對(duì)象從原來(lái)的80M,變成了160M甚至更多,Survior區(qū)200M空間,他的一半小于160M, 所以會(huì)直接放入到老年代。針對(duì)這個(gè)問(wèn)題,我們來(lái)做參數(shù)優(yōu)化。

          優(yōu)化一:分代年齡從15變成5

          系統(tǒng)默認(rèn)的分代年齡是15,也就是一個(gè)對(duì)象在Survivor兩個(gè)區(qū)輪回15次才會(huì)進(jìn)入到老年代。15次大概是多長(zhǎng)時(shí)間呢?我們來(lái)計(jì)算一下,按照參數(shù)來(lái)分析一下內(nèi)存模型,如下圖:

          ‐Xms3072M ‐Xmx3072M ‐Xmn2048M ‐Xss1M ‐XX:MetaspaceSize=256M ‐XX:MaxMetaspaceSize=256M ‐XX:SurvivorRatio=8
          復(fù)制代碼

          每秒鐘產(chǎn)生80M垃圾,放入到Eden區(qū),Eden區(qū)一共1.6G,預(yù)計(jì)20s放滿,觸發(fā)Minor GC, 然后大部分對(duì)象被回收,只有一小部分對(duì)象進(jìn)入到Survivor區(qū)。第二次回收的時(shí)候,上次進(jìn)入Survivor區(qū)的大部分對(duì)象被垃圾回收,另一部分進(jìn)入到另一個(gè)Survivor區(qū)。這些進(jìn)入到另一個(gè)Survivor的對(duì)象要經(jīng)歷15次Minor GC,也就是年齡是15的時(shí)候,被轉(zhuǎn)移到老年代,花費(fèi)大約20s*15約5分鐘的時(shí)間才能進(jìn)入到老年代。其實(shí)這些長(zhǎng)期存活的對(duì)象都是java運(yùn)行或者spring運(yùn)行是的一些java.lang.String, java.util.Math, 和一些bean對(duì)象。既然這些對(duì)象本身是長(zhǎng)期存活的,那么我們就沒(méi)必要讓他經(jīng)歷那么多代才進(jìn)入到老年代。

          我們完全可以將默認(rèn)的15歲改小一點(diǎn),比如改為5,那么意味著對(duì)象要經(jīng)過(guò)5次minor gc才會(huì)進(jìn)入老年代,如果經(jīng)歷5次Minor GC還沒(méi)有被回收,我們完全可以認(rèn)為她就是要長(zhǎng)期存活的對(duì)象了,將其移動(dòng)到老年代,而不是繼續(xù)一直占用survivor區(qū)空間。整個(gè)過(guò)程時(shí)間不到兩分鐘。

          設(shè)置參數(shù)如下:

          ‐Xms3072M ‐Xmx3072M ‐Xmn2048M ‐Xss1M ‐XX:MetaspaceSize=256M ‐XX:MaxMetaspaceSize=256M ‐XX:SurvivorRatio=8 ?
          ‐XX:MaxTenuringThreshold=5
          復(fù)制代碼

          優(yōu)化二:大對(duì)象直接進(jìn)入老年代

          對(duì)于多大的對(duì)象直接進(jìn)入老年代合適呢?這個(gè)一般可以結(jié)合你自己系統(tǒng)看下有沒(méi)有什么大對(duì)象生成,預(yù)估下大對(duì)象的大小,一般來(lái)說(shuō)設(shè)置為1M就差不多了,很少有超過(guò)1M的大對(duì)象,這些對(duì)象一般就是你系統(tǒng)初始化分配的緩存對(duì)象,比如大的緩存List,Map之類的對(duì)象。設(shè)置大對(duì)象直接進(jìn)入老年代使用的參數(shù):-XX:PretenureSizeThreshold

          參數(shù)設(shè)置如下:

          ‐Xms3072M ‐Xmx3072M ‐Xmn2048M ‐Xss1M ‐XX:MetaspaceSize=256M ‐XX:MaxMetaspaceSize=256M ‐XX:SurvivorRatio=8 ?
          ‐XX:MaxTenuringThreshold=5 ‐XX:PretenureSizeThreshold=1M
          復(fù)制代碼

          優(yōu)化三:替換垃圾收集器為ParNew + CMS

          JDK8默認(rèn)使用的垃圾回收器是-XX:+UseParallelGC(年輕代)和-XX:+UseParallelOldGC(老年代),通常使用Parallel會(huì)有什么問(wèn)題呢?經(jīng)驗(yàn)告訴我們,當(dāng)系統(tǒng)內(nèi)存較大的時(shí)候(超過(guò)4G,經(jīng)驗(yàn)值),系統(tǒng)對(duì)停頓時(shí)間是比較敏感的。通常大于4G內(nèi)存,我們可以采用ParNew + CMS垃圾收集器??刹豢梢允褂肎1收集器呢?G1收集器通常是內(nèi)存大于8G時(shí)使用的。內(nèi)存小于8G時(shí),在jdk8中G1收集器的算法耗費(fèi)的內(nèi)存要比CMS多。所以這里我們替換垃圾收集器為ParNew + CMS。設(shè)置使用ParNew + CMS的參數(shù)是:-XX:+UseParNewGC -XX:+UseConcMarkSweepGC

          經(jīng)驗(yàn):很多使用jdk8的公司都是用時(shí)ParNew + CMS垃圾回收

          參數(shù)設(shè)置如下:

          ‐Xms3072M ‐Xmx3072M ‐Xmn2048M ‐Xss1M ‐XX:MetaspaceSize=256M ‐XX:MaxMetaspaceSize=256M ‐XX:SurvivorRatio=8 ?
          ‐XX:MaxTenuringThreshold=5 ‐XX:PretenureSizeThreshold=1M -XX:+UseParNewGC -XX:+UseConcMarkSweepGC
          復(fù)制代碼

          替換成ParNew + CMS垃圾收集器能解決上面并發(fā)流量達(dá)到700~1000單/s的問(wèn)題么?我們來(lái)分析一下:

          1) 當(dāng)并發(fā)流量導(dǎo)到700單/s的時(shí)候, 原來(lái)每秒產(chǎn)生80M垃圾,現(xiàn)在可能達(dá)到160M,那么年輕代Survivor放不下,會(huì)直接放入到老年代。

          2)當(dāng)兵發(fā)流量大了的時(shí)候,本來(lái)系統(tǒng)能承受的是400單/s, 但是突增到500單/s的時(shí)候,原來(lái)每秒可以處理一個(gè)訂單,現(xiàn)在可能1秒處理不完了,要2秒甚至更多。那么就有可能在垃圾回收的時(shí)候,2s內(nèi)的對(duì)象的引用關(guān)系都還在,不能被回收,剛好又大于新生代一半的空間,也會(huì)被直接放入老年代。

          3)經(jīng)過(guò)上面的優(yōu)化,發(fā)生一次Minor GC,大約要20s, 老年代有1G空間,1G/160M*20/60=2分鐘。2分鐘觸發(fā)一次GC,通常高峰流量也就半個(gè)小時(shí)左右。2分鐘觸發(fā)一次GC,這也不太合適。

          優(yōu)化四:設(shè)置CMS收集器的參數(shù)

          1) 避免并發(fā)失敗參數(shù)設(shè)置

          在CMS收集器那塊我們說(shuō)過(guò),CMS正在收集垃圾但還沒(méi)有完成的時(shí)候,又產(chǎn)生了新的垃圾,導(dǎo)致再次觸發(fā)垃圾回收,這就發(fā)生死循環(huán)了,這就是concurrentmode failure并發(fā)失敗。為了避免并發(fā)失敗,這時(shí)會(huì)停止CMS垃圾回收的全部線程,進(jìn)入到Serial Old串行垃圾收集。串行速度是很慢的,嚴(yán)重影響用戶體驗(yàn)。我們盡量不要讓這種情況發(fā)生。因此,我們?cè)O(shè)置垃圾回收參數(shù):‐XX:CMSInitiatingOccupancyFraction,我們?cè)O(shè)置老年代達(dá)到一定比例比如80%就出發(fā)Full GC,留出足夠大的空間給大對(duì)象,這樣就不會(huì)觸發(fā)Serial Old了。

          這個(gè)值默認(rèn)是92,也可以設(shè)置成80,但設(shè)置成80就表示,剩下20%的內(nèi)存空間正常情況下處于閑置了。

          參數(shù)設(shè)置如下:

          ‐Xms3072M ‐Xmx3072M ‐Xmn2048M ‐Xss1M ‐XX:MetaspaceSize=256M ‐XX:MaxMetaspaceSize=256M ‐XX:SurvivorRatio=8 ?
          ‐XX:MaxTenuringThreshold=5 ‐XX:PretenureSizeThreshold=1M -XX:+UseParNewGC -XX:+UseConcMarkSweepGC
          ‐XX:CMSInitiatingOccupancyFraction=92
          復(fù)制代碼

          2)壓縮整理參數(shù)設(shè)置

          我們可以設(shè)置在發(fā)生Full GC之后進(jìn)行內(nèi)存空間的壓縮整理。這里涉及到兩個(gè)參數(shù),一個(gè)是開(kāi)啟壓縮整理,另一個(gè)是觸發(fā)幾次Full GC整理一次內(nèi)存空間。

          -XX:+UseCMSCompactAtFullCollection:FullGC之后做壓縮整理(減少碎片) 
          -XX:CMSFullGCsBeforeCompaction:多少次FullGC之后壓縮一次,默認(rèn)是0,代表每次FullGC后都會(huì)壓縮一次
          ?這個(gè)參數(shù)是說(shuō)執(zhí)行多少次Full GC以后進(jìn)行一次壓縮。如果其值是3,則表示執(zhí)行3次Full GC,進(jìn)行一次壓縮整理。
          復(fù)制代碼

          在觸發(fā)了CMS垃圾回收之后,進(jìn)行內(nèi)存整理,也會(huì)對(duì)性能有一定的影響的。因?yàn)樗矔?huì)STW。這個(gè)過(guò)程不會(huì)特別慢,這和剩余的對(duì)象有關(guān),剩余的對(duì)象少,效率就高。剩余的對(duì)象多,效率就低。因?yàn)樵谡淼倪^(guò)程中,對(duì)象的地址會(huì)發(fā)生變化。

          對(duì)于我們上面的案例,我們可以設(shè)置每次垃圾回收后都進(jìn)行整理,為什么可以這么設(shè)置呢?因?yàn)槲覀僨ull GC發(fā)生的頻率很低。偶爾搞一次大促呢?也沒(méi)關(guān)系,大促的前面二三十分鐘流量最高,二三十分鐘觸發(fā)一次Full GC沒(méi)關(guān)系的,因?yàn)榇蟠倩窘Y(jié)束了。

          如果系統(tǒng)壓力比較大,觸發(fā)Full GC很頻繁,這個(gè)參數(shù)就不要這么設(shè)置了。可以設(shè)置-XX:CMSFullGCsBeforeCompaction為3次,5次。

          不做碎片整理可不可以呢?

          最好不要,因?yàn)槿绻蛔鏊槠?,老年代的碎片就?huì)越來(lái)越多,正常的大對(duì)象都放不下了。

          參數(shù)設(shè)置如下:

          ‐Xms3072M ‐Xmx3072M ‐Xmn2048M ‐Xss1M ‐XX:MetaspaceSize=256M ‐XX:MaxMetaspaceSize=256M ‐XX:SurvivorRatio=8 ?
          ‐XX:MaxTenuringThreshold=5 ‐XX:PretenureSizeThreshold=1M -XX:+UseParNewGC -XX:+UseConcMarkSweepGC
          ‐XX:CMSInitiatingOccupancyFraction=92 ‐XX:+UseCMSCompactAtFullCollection ‐XX:CMSFullGCsBeforeC


          作者:summerSunShine
          鏈接:https://juejin.cn/post/7022433974563635230
          來(lái)源:稀土掘金
          著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。



          瀏覽 41
          點(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>
                  亚洲AV永久无码国产精品国产 | 蜜桃视频在线无码播放 | 91中文字幕在线观看 | 性v天堂 | 亚洲中国操逼视屏 |