1耙蔑、Zookeeper:
ZAB(zookeeper atomic broadcast)協(xié)議是zookeeper用于保證分布式數(shù)據(jù)最終一致性的宵凌。
ZK角色:
leader:負(fù)責(zé)數(shù)據(jù)讀寫(xiě)
follower:負(fù)責(zé)數(shù)據(jù)讀,具有選舉權(quán)
observer:負(fù)責(zé)數(shù)據(jù)讀隅居,無(wú)選舉權(quán)钠至。
數(shù)據(jù)讀流程:client ->任意zk節(jié)點(diǎn)->返回?cái)?shù)據(jù)
數(shù)據(jù)寫(xiě)流程:client->任意zk節(jié)點(diǎn)->轉(zhuǎn)發(fā)數(shù)據(jù)到leader->發(fā)送proposal到所有follower->等待半數(shù)以上節(jié)點(diǎn)ACK->向follower發(fā)送commit指令,同時(shí)本機(jī)commit->返回client成功
1.1胎源、Zab 協(xié)議的特性:
1)Zab 協(xié)議需要確保那些已經(jīng)在 Leader 服務(wù)器上提交(Commit)的事務(wù)最終被所有的服務(wù)器提交棉钧。
2)Zab 協(xié)議需要確保丟棄那些只在 Leader 上被提出而沒(méi)有被提交的事務(wù)。
選舉規(guī)則:
zxid>serverId
1.2乒融、數(shù)據(jù)恢復(fù):
場(chǎng)景1:leader在未發(fā)送所有commit請(qǐng)求前宕機(jī)掰盘,可能部分或所有節(jié)點(diǎn)未接收到commit指令摄悯。
先選舉,選擇zxid最大的節(jié)點(diǎn)(該節(jié)點(diǎn)數(shù)據(jù)最新)愧捕,即使該節(jié)點(diǎn)存在未commit的proposal奢驯,也能保證數(shù)據(jù)不丟失。
leader 將本機(jī)的proposal同步至follower次绘,并對(duì)未commit的proposal發(fā)送commit指令瘪阁,保證數(shù)據(jù)不丟失。
場(chǎng)景2:leader在剛接收到proposal時(shí)宕機(jī)邮偎,此時(shí)尚未發(fā)送proposal到follower管跺。
先選舉,選擇zxid最大的節(jié)點(diǎn)禾进,此時(shí)原來(lái)的leader恢復(fù)豁跑,與新leader進(jìn)行數(shù)據(jù)同步,老leader丟棄尚未commit的proposal泻云。
2艇拍、HTTP協(xié)議
3、網(wǎng)絡(luò)分層
3.1宠纯、OSI七層模型
層級(jí) | 協(xié)議 | 描述 |
---|---|---|
應(yīng)用層 | HTTP FTP | 應(yīng)用層的功能就是規(guī)定了應(yīng)用程序的數(shù)據(jù)格式卸夕。我們經(jīng)常用的電子郵件、HTTP協(xié)議以及FTP數(shù)據(jù)的格式婆瓜,就是在應(yīng)用層定義的快集。 |
表示層 | TELNET | |
會(huì)話(huà)層 | DNS SMTP | |
傳輸層 | TCP UDP | 經(jīng)過(guò)數(shù)據(jù)鏈路層和網(wǎng)絡(luò)層的支持,我們已經(jīng)可以正常在兩臺(tái)計(jì)算機(jī)之間進(jìn)行通訊了廉白,但是計(jì)算機(jī)會(huì)同時(shí)運(yùn)行著許多程序个初,比如同時(shí)開(kāi)著QQ與WX,那么怎么區(qū)分消息是QQ的還是WX的呢蒙秒?傳輸層的功能就是建立端口到端口的通信勃黍,使得數(shù)據(jù)能夠正確的傳送給不同的應(yīng)用程序宵统。 |
網(wǎng)絡(luò)層 | IP ICMP | 以太網(wǎng)通過(guò)廣播這種很原始的形式晕讲,解決了兩臺(tái)計(jì)算機(jī)之間的通信問(wèn)題。但很明顯马澈,它不是把數(shù)據(jù)包準(zhǔn)確的送達(dá)接收方瓢省,而是向網(wǎng)絡(luò)中所有的計(jì)算機(jī)發(fā)送數(shù)據(jù)包。網(wǎng)絡(luò)層引入一套新的協(xié)議用來(lái)區(qū)分不同的廣播域/子網(wǎng)痊班,于是就有了IP 協(xié)議勤婚。. |
數(shù)據(jù)鏈路層 | 以太網(wǎng) | 數(shù)據(jù)鏈路層的功能就是通過(guò)規(guī)定一套協(xié)議來(lái)定義電信號(hào)的分組方式,以及規(guī)定不同的組代表什么意思涤伐,從而雙方計(jì)算機(jī)都能夠進(jìn)行識(shí)別馒胆,這個(gè)協(xié)議就是“以太網(wǎng)協(xié)議”缨称。 |
物理層 | RS232 | 物理層,顧名思義祝迂,用物理手段將電腦連接起來(lái)睦尽,基本上是用雙絞線(xiàn)、光纖型雳、無(wú)線(xiàn)電波的方式來(lái)實(shí)現(xiàn)物理層当凡。 |
3.2、TCP/IP4層模型
應(yīng)用層
傳輸層
網(wǎng)絡(luò)層
網(wǎng)絡(luò)接口層
3.3纠俭、TCP/IP5層模型
應(yīng)用層
傳輸層
網(wǎng)絡(luò)層
數(shù)據(jù)鏈路層
物理層
4沿量、TCP協(xié)議
4.1、TCP 最主要的特點(diǎn)
- TCP 是面向連接的傳輸層協(xié)議冤荆。應(yīng)用程序在使用 TCP 協(xié)議之前朴则,必須先建立 TCP 連接。在傳送數(shù)據(jù)完畢后钓简,必須釋放已經(jīng)建立的 TCP 連接
- 每一條 TCP 連接只能有兩個(gè)端點(diǎn)佛掖,每一條 TCP 連接只能是點(diǎn)對(duì)點(diǎn)的(一對(duì)一)
- TCP 提供可靠交付的服務(wù)。通過(guò) TCP 連接傳送的數(shù)據(jù)涌庭,無(wú)差錯(cuò)芥被、不丟失、不重復(fù)坐榆,并且按序到達(dá)
- TCP 提供全雙工通信拴魄。TCP 允許通信雙方的應(yīng)用進(jìn)程在任何時(shí)候都能發(fā)送數(shù)據(jù)。TCP 連接的兩端都設(shè)有發(fā)送緩存和接受緩存席镀,用來(lái)臨時(shí)存放雙向通信的數(shù)據(jù)
- 面向字節(jié)流匹中。TCP 中的“流”指的是流入到進(jìn)程或從進(jìn)程流出的字節(jié)序列
4.2、報(bào)文頭
- ACK:只有1 bit的標(biāo)志位豪诲,若為1顶捷,表示這個(gè)數(shù)據(jù)段中的確認(rèn)序號(hào)是有效的,即這個(gè)數(shù)據(jù)報(bào)是對(duì)之前接收到的某個(gè)報(bào)文的確認(rèn)(一個(gè)TCP報(bào)文可以同時(shí)作為確認(rèn)報(bào)文和傳遞數(shù)據(jù)報(bào)文)屎篱。
- RST:只有1 bit的標(biāo)志位服赎,若客戶(hù)端向服務(wù)器的一個(gè)端口請(qǐng)求建立TCP連接,但是服務(wù)器的那個(gè)端口并不允許建立連接(比如沒(méi)開(kāi)啟此端口)交播,則服務(wù)器會(huì)回送一個(gè)TCP報(bào)文重虑,將RST位置為1,告訴客戶(hù)端不要再向這個(gè)端口發(fā)起連接秦士;
- SYN:只有1 bit的標(biāo)志位缺厉,若為1,表示這是一條建立連接的TCP報(bào)文段;
- FIN:只有1 bit的標(biāo)志位提针,若為1命爬,表示這是一條斷開(kāi)連接的TCP報(bào)文段;
4.2辐脖、三次握手
客戶(hù)端 -> 服務(wù)端 : syn=1 seq = x
服務(wù)端 -> 客戶(hù)端:syn=1 ack =1 ack=x+ 1 seq = y
客戶(hù)端 -> 服務(wù)端:ack=1 ack=y+1 seq=x+1
4.3遇骑、四次揮手
客戶(hù)端 -> 服務(wù)端:fin=1 seq=x,客戶(hù)端向服務(wù)端發(fā)起斷開(kāi)連接請(qǐng)求揖曾,客戶(hù)端已無(wú)數(shù)據(jù)發(fā)送落萎。
服務(wù)端 -> 客戶(hù)端:fin=1 ack=1 ack=x+1 seq=y,服務(wù)端接收到請(qǐng)求炭剪,向客戶(hù)端發(fā)送確認(rèn)報(bào)文练链,此時(shí)服務(wù)端處于CLOSE_WAIT狀態(tài)。
服務(wù)端 -> 客戶(hù)端:fin=1 ack=1 ack=x+1 seq=u奴拦,服務(wù)端完成數(shù)據(jù)發(fā)送后媒鼓,向客戶(hù)端斷開(kāi)連接。
客戶(hù)端 -> 服務(wù)端:ack=1 ack=u+1 seq=x+1错妖,客戶(hù)端接收到請(qǐng)求绿鸣,向服務(wù)端發(fā)送確認(rèn)報(bào)文,服務(wù)端收到ACK后立刻斷開(kāi)連接暂氯。此時(shí)客戶(hù)端處于TIME_WAIT狀態(tài)潮模,此時(shí)客戶(hù)端側(cè)連接尚未關(guān)閉,等待2MSL(Maximum Segment LifeTime)后痴施,會(huì)立即進(jìn)入CLOSED關(guān)閉狀態(tài)擎厢,到這里TCP連接就斷開(kāi)了。
為什么客戶(hù)端要等待2MSL辣吃?
主要原因是為了保證客戶(hù)端發(fā)送那個(gè)的第一個(gè)ACK報(bào)文能到到服務(wù)器动遭,因?yàn)檫@個(gè)ACK報(bào)文可能丟失,并且2MSL是任何報(bào)文在網(wǎng)絡(luò)上存在的最長(zhǎng)時(shí)間神得,超過(guò)這個(gè)時(shí)間報(bào)文將被丟棄厘惦,這樣新的連接中不會(huì)出現(xiàn)舊連接的請(qǐng)求報(bào)文。
5哩簿、IO模型
5.1宵蕉、BIO
使用BIO通信模型的服務(wù)端,通常通過(guò)一個(gè)獨(dú)立的Acceptor線(xiàn)程負(fù)責(zé)監(jiān)聽(tīng)客戶(hù)端的連接卡骂,監(jiān)聽(tīng)到客戶(hù)端連接請(qǐng)求后為每一個(gè)客戶(hù)端創(chuàng)建一個(gè)新的線(xiàn)程鏈路進(jìn)行處理国裳,處理完成通過(guò)輸出流回應(yīng)客戶(hù)端形入,線(xiàn)程消耗全跨,這就是典型一對(duì)一答模型。
服務(wù)端
int port = 3000;
try(ServerSocket serverSocket = new ServerSocket(port)) {
Socket socket = null;
while (true) {
//主程序阻塞在accept操作上
socket = serverSocket.accept();
new Thread(new BioExampleServerHandle(socket)).start();
}
} catch (Exception e) {
e.printStackTrace();
}
private Socket socket;
public BioExampleServerHandle(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try(BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter writer = new PrintWriter(socket.getOutputStream(), true)) {
String message = reader.readLine();
System.out.println("收到客戶(hù)端消息:" + message);
writer.println("answer: " + message);
} catch (Exception e) {
e.printStackTrace();
}
}
客戶(hù)端
String host = "127.0.0.1";
int port = 3000;
try(Socket socket = new Socket(host, port);
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter writer = new PrintWriter(socket.getOutputStream(), true)) {
Scanner input = new Scanner(System.in);
System.out.println("輸入你想說(shuō)的話(huà):");
String message = input.nextLine();
writer.println(message);
String answer = reader.readLine();
System.out.println(answer);
} catch (Exception e) {
e.printStackTrace();
}
5.2亿遂、NIO
NIO 彌補(bǔ)了同步阻塞I/O的不足浓若,它提供了高速渺杉、面向塊的I/O,我們對(duì)一些概念介紹一下:
Buffer: Buffer用于和NIO通道進(jìn)行交互挪钓。數(shù)據(jù)從通道讀入緩沖區(qū)是越,從緩沖區(qū)寫(xiě)入到通道中,它的主要作用就是和Channel進(jìn)行交互。
Channel: Channel是一個(gè)通道碌上,可以通過(guò)它讀取和寫(xiě)入數(shù)據(jù)倚评,通道是雙向的,通道可以用于讀馏予、寫(xiě)或者同時(shí)讀寫(xiě)天梧。
Selector: Selector會(huì)不斷的輪詢(xún)注冊(cè)在它上面的Channe,如果Channel上面有新的連接讀寫(xiě)事件的時(shí)候就會(huì)被輪詢(xún)出來(lái),一個(gè)Selector可以注冊(cè)多個(gè)Channel霞丧,只需要一個(gè)線(xiàn)程負(fù)責(zé)Selector輪詢(xún)呢岗,就可以支持成千上萬(wàn)的連接,可以說(shuō)為高并發(fā)服務(wù)器的開(kāi)發(fā)提供了很好的支撐蛹尝。
5.3后豫、AIO
NIO2.0 引入了異步通道的概念,提供了異步文件通道和異步套接字通道的實(shí)現(xiàn)突那,我們可以通過(guò)Future類(lèi)來(lái)表示異步操作結(jié)果挫酿,也可以在執(zhí)行異步操作的時(shí)候傳入一個(gè)Channels,實(shí)現(xiàn)CompletionHandler接口為操作回調(diào)。
5.4愕难、對(duì)比
對(duì)比項(xiàng) | 同步阻塞I/O(BIO) | 偽異步I/O | 非阻塞I/O(NIO) | 異步I/O(AIO) |
---|---|---|---|---|
是否阻塞 | 是 | 是 | 否 | 否 |
是否同步 | 是 | 是 | 是 | 否(異步) |
友好程度 | 簡(jiǎn)單 | 簡(jiǎn)單 | 非常難 | 比較難 |
可靠性 | 非常差 | 差 | 高 | 高 |
吞吐量 | 低 | 中 | 高 | 高 |
6饭豹、JVM
6.1、JVM組成
- 程序計(jì)數(shù)器:線(xiàn)程私有务漩,生命周期跟隨線(xiàn)程拄衰,記錄程序當(dāng)前執(zhí)行指令的地址。
- 虛擬機(jī)棧(線(xiàn)程棧):虛擬機(jī)棧描述的是Java方法執(zhí)行的內(nèi)存模型饵骨,每個(gè)方法在執(zhí)行的同時(shí)都會(huì)創(chuàng)建一個(gè)棧幀(Stack Frame)用于存儲(chǔ)局部變量表翘悉、操作數(shù)棧、動(dòng)態(tài)鏈接居触、方法出口等信息妖混。每一個(gè)方法從調(diào)用直至執(zhí)行完成的過(guò)程,就對(duì)應(yīng)著一個(gè)棧幀在虛擬機(jī)棧中入棧到出棧的過(guò)程轮洋。
- 本地方法棧:線(xiàn)程私有制市,執(zhí)行本地方法。
- 堆:線(xiàn)程共享弊予,此內(nèi)存區(qū)域的唯一目的就是存放對(duì)象實(shí)例祥楣,幾乎所有的對(duì)象實(shí)例都在這里分配內(nèi)存。分為young和old區(qū),young分為2塊survivor和一塊eden
6.2误褪、JVM配置
- -Xss 設(shè)置每個(gè)線(xiàn)程的棧大小责鳍。JDK1.5+ 每個(gè)線(xiàn)程棧大小為1M,以-X開(kāi)頭的參數(shù)是和實(shí)現(xiàn)有關(guān)的兽间,第一個(gè)s表示stack历葛,第二個(gè)s表示size。
- -Xms 設(shè)置堆的最小空間大朽致浴恤溶;通常為操作系統(tǒng)可用內(nèi)存的1/64大小即可。
- -Xmx 設(shè)置堆的最大空間大兄难颉宏娄;通常為操作系統(tǒng)可用內(nèi)存的1/4大小。
- -Xmn 設(shè)置新生代大小逮壁,是對(duì)-XX:newSize孵坚、-XX:MaxnewSize兩個(gè)參數(shù)的同時(shí)配置,這個(gè)參數(shù)是在JDK1.4版本以后出現(xiàn)的窥淆;通常為Xmx的1/3或1/4卖宠。新生代 = Eden + 2個(gè)Survivor空間。實(shí)際可用空間 = Eden + 1個(gè)Survivor忧饭,即90%扛伍。
- -XX:NewSize 設(shè)置新生代最小空間大小词裤;
- -XX:MaxNewSize 設(shè)置新生代最大空間大写倘鳌;
- -XX:NewRatio 新生代與老年代的比例吼砂,如-XX:NewRatio=2逆航,則新生代占整個(gè)堆空間的1/3岛琼,老年代占2/3废累。
- -XX:SurvivorRatio 新生代中 Eden 與 Survivor的比值定踱。默認(rèn)值為 8 变勇。即Eden占新生代空間的8/10,另外兩個(gè)Survivor各占1/10缆巧。
6.3司抱、垃圾回收器
6.3.1绪励、回收算法
引用計(jì)數(shù)算法
為每個(gè)對(duì)象創(chuàng)建一個(gè)引用計(jì)數(shù)蓉坎,有對(duì)象引用時(shí)計(jì)數(shù)器 +1澳眷,引用被釋放時(shí)計(jì)數(shù) -1,當(dāng)計(jì)數(shù)器為 0 時(shí)就可以被回收蛉艾。但是他有一個(gè)缺點(diǎn)是不能解決循環(huán)引用的問(wèn)題钳踊。
可達(dá)性分析算法
從 GC Roots 開(kāi)始向下搜索衷敌,搜索所走過(guò)的路徑稱(chēng)為引用鏈。當(dāng)一個(gè)對(duì)象到 GC Roots 沒(méi)有任何引用鏈相連時(shí)箍土,則證明此對(duì)象是可以被回收的逢享。
標(biāo)記-清除算法
標(biāo)記無(wú)用對(duì)象罐监,然后進(jìn)行清除回收吴藻。缺點(diǎn):效率不高,無(wú)法清除垃圾碎片弓柱。
該算法分為兩個(gè)階段沟堡,標(biāo)記和清除。標(biāo)記階段標(biāo)記所有需要回收的對(duì)象矢空,清除階段回收被標(biāo)記的對(duì)象所占用的空間航罗。該算法最大的問(wèn)題就是內(nèi)存碎片嚴(yán)重化,后續(xù)可能發(fā)生對(duì)象不能找到利用空間的問(wèn)題屁药。
復(fù)制算法
按照容量劃分二個(gè)大小相等的內(nèi)存區(qū)域粥血,當(dāng)一塊用完的時(shí)候?qū)⒒钪膶?duì)象復(fù)制到另一塊上,然后再把已使用的內(nèi)存空間一次清理掉酿箭。缺點(diǎn):內(nèi)存使用率不高复亏,只有原來(lái)的一半。
按內(nèi)存容量將內(nèi)存劃分為等大小的兩塊缭嫡。每次只使用其中一塊缔御,當(dāng)這一塊內(nèi)存滿(mǎn)后將尚存活的對(duì)象復(fù)制到另一塊上去,把已使用的內(nèi)存清掉妇蛀。
標(biāo)記-整理算法
標(biāo)記無(wú)用對(duì)象耕突,讓所有存活的對(duì)象都向一端移動(dòng),然后直接清除掉端邊界以外的內(nèi)存评架。
標(biāo)記后不是清理對(duì)象眷茁,而是將存活對(duì)象移向內(nèi)存的一端。然后清除端邊界外的對(duì)象纵诞。
分代算法
根據(jù)對(duì)象存活周期的不同將內(nèi)存劃分為幾塊蔼卡,一般是新生代和老年代,新生代基本采用復(fù)制算法挣磨,老年代采用標(biāo)記整理算法雇逞。當(dāng)前商業(yè)虛擬機(jī)都采用分代收集的垃圾收集算法。分代收集算法茁裙,顧名思義是根據(jù)對(duì)象的存活周期將內(nèi)存劃分為幾塊塘砸。一般包括年輕代、老年代 和 永久代晤锥。
三色標(biāo)記法
//TODO
6.3.2掉蔬、垃圾回收器
垃圾回收器名稱(chēng) | 適用內(nèi)存區(qū)域 | 并發(fā)類(lèi)型 | 回收算法 | 優(yōu)點(diǎn) | 缺點(diǎn) |
---|---|---|---|---|---|
Serial | 新生代 | 單線(xiàn)程 | 復(fù)制算法 | 簡(jiǎn)單高效廊宪,對(duì)于限定單個(gè)CPU的環(huán)境來(lái)說(shuō),Serial垃圾收集器沒(méi)有線(xiàn)程交互(交換)開(kāi)銷(xiāo)女轿,可以獲得最高的單線(xiàn)程手機(jī)效率 | 會(huì)發(fā)生SWT現(xiàn)象 |
ParNew | 新生代 | 多線(xiàn)程 | 復(fù)制算法 | Serial多線(xiàn)程版本箭启,并行處理能力變強(qiáng) | 會(huì)發(fā)生SWT現(xiàn)象 |
Parallel Scavange | 新生代 | 多線(xiàn)程 | 復(fù)制算法 | 關(guān)注系統(tǒng)吞吐量 | |
Serial Old | 老年代 | 單線(xiàn)程 | 標(biāo)記整理算法 | STW | |
Parallel Old | 老年代 | 多線(xiàn)程 | 標(biāo)記整理 | 關(guān)注系統(tǒng)吞吐量 | |
CMS | 老年代 | 多線(xiàn)程 | 標(biāo)記清理 | 獲取最短垃圾回收停頓時(shí)間 | 產(chǎn)生大量的內(nèi)存碎片,對(duì)CPU資源敏感 |
G1 | 老年代/新生代 | 多線(xiàn)程 | 標(biāo)記-整理算法+復(fù)制算法 | 低停頓 + 停頓時(shí)間可控 |
CMS運(yùn)行過(guò)程
Concurrent Mark Sweep (CMS)垃圾收集器時(shí)針對(duì)老年代的一個(gè)并發(fā)線(xiàn)程的垃圾收集器蛉迹,其目的是獲取最短垃圾回收停頓時(shí)間傅寡,它采用的是多線(xiàn)程的標(biāo)記—清除,但是它需要更多的內(nèi)存來(lái)完成這個(gè)動(dòng)作北救;多應(yīng)用于:
- 與用戶(hù)交互較多的場(chǎng)景
- 希望系統(tǒng)的停頓時(shí)間最短荐操,注重服務(wù)的響應(yīng)速度
- 給用戶(hù)帶來(lái)較好的體驗(yàn)
- 常見(jiàn)的WEB、B/S系統(tǒng)的服務(wù)器應(yīng)用上
- 初始標(biāo)記
只是標(biāo)記一下GC Roots能直接關(guān)聯(lián)的對(duì)象珍策,速度很快但仍然需要暫停所有的工作線(xiàn)程托启; - 并發(fā)標(biāo)記
進(jìn)行GC Roots跟蹤的過(guò)程,從剛才產(chǎn)生的集合中標(biāo)記存活的對(duì)象攘宙,并發(fā)執(zhí)行不需要暫停工作線(xiàn)程屯耸;
但是并不能保證標(biāo)記出所有的存活對(duì)象; - 重新標(biāo)記
為了修正并發(fā)標(biāo)記期間因?yàn)橛脩?hù)程序繼續(xù)運(yùn)行而導(dǎo)致標(biāo)記變動(dòng)的那一部分對(duì)象的標(biāo)記記錄蹭劈;需要“Stop The World”且停頓時(shí)間比初始標(biāo)記時(shí)間長(zhǎng)但遠(yuǎn)比并發(fā)標(biāo)記的時(shí)間短疗绣; - 并發(fā)清除
回收所有的垃圾對(duì)象;
CMS另兩個(gè)致命缺陷
- CMS采用了Mark-Sweep算法链方,最后會(huì)產(chǎn)生許多內(nèi)存碎片持痰,當(dāng)?shù)揭欢〝?shù)量時(shí),CMS無(wú)法清理這些碎片了祟蚀,CMS會(huì)讓Serial Old垃圾處理器來(lái)清理這些垃圾碎片工窍,而Serial Old垃圾處理器是單線(xiàn)程操作進(jìn)行清理垃圾的,效率很低前酿。
所以使用CMS就會(huì)出現(xiàn)一種情況患雏,硬件升級(jí)了,卻越來(lái)越卡頓罢维,其原因就是因?yàn)檫M(jìn)行Serial Old GC時(shí)淹仑,效率過(guò)低。
解決方案:使用Mark-Sweep-Compact算法肺孵,減少垃圾碎片
調(diào)優(yōu)參數(shù)(配套使用):
開(kāi)啟CMS的壓縮
-XX:+UseCMSCompactAtFullCollection
//默認(rèn)為0匀借,指經(jīng)過(guò)多少次CMS FullGC才進(jìn)行壓縮
-XX:CMSFullGCsBeforeCompaction
- 當(dāng)JVM認(rèn)為內(nèi)存不夠,再使用CMS進(jìn)行并發(fā)清理內(nèi)存可能會(huì)發(fā)生OOM的問(wèn)題平窘,而不得不進(jìn)行Serial Old GC吓肋,Serial Old是單線(xiàn)程垃圾回收,效率低
解決方案:降低觸發(fā)CMS GC的閾值瑰艘,讓浮動(dòng)垃圾不那么容易占滿(mǎn)老年代
-XX:CMSInitiatingOccupancyFraction 92%
//可以降低這個(gè)值是鬼,讓老年代占用率達(dá)到該值就進(jìn)行CMS GC