多任務(wù)環(huán)境中性能問(wèn)題怎樣才能不讓程序互相干擾_第1頁(yè)
多任務(wù)環(huán)境中性能問(wèn)題怎樣才能不讓程序互相干擾_第2頁(yè)
多任務(wù)環(huán)境中性能問(wèn)題怎樣才能不讓程序互相干擾_第3頁(yè)
多任務(wù)環(huán)境中性能問(wèn)題怎樣才能不讓程序互相干擾_第4頁(yè)
多任務(wù)環(huán)境中性能問(wèn)題怎樣才能不讓程序互相干擾_第5頁(yè)
已閱讀5頁(yè),還剩11頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

27|多任務(wù)環(huán)境中的Java2020-01-27莊振性能27|多任務(wù)環(huán)境中的Java2020-01-27莊振性能工程高進(jìn)入課20:44大小你好,我是莊振但是,萬(wàn)事有利就有弊。這幾個(gè)共存的應(yīng)用程序,有可能會(huì)互相影響;有時(shí)還會(huì)導(dǎo)致嚴(yán)性能問(wèn)題。我就遇到過(guò),幾個(gè)程序同時(shí)運(yùn)行,最后導(dǎo)致吞吐量急劇下降所以,今天我們就來(lái)探討,當(dāng)多個(gè)Java應(yīng)用程序共存在一個(gè)Linux系統(tǒng)上的時(shí)候,會(huì)產(chǎn)生下載們運(yùn)行的是Java程序,所以先快速?gòu)?fù)習(xí)一下Java的JVM內(nèi)存管理機(jī)制。Java程序在Java虛擬機(jī)JVM中運(yùn)行,JVM使用的內(nèi)存區(qū)域稱為堆。JVM堆用于支持動(dòng)態(tài)Java象的分配,并且分為幾個(gè)區(qū)域,稱為“代”(例如新生代和老年代)。Java首先在新生代中分配;當(dāng)這些對(duì)象不再被需要時(shí),它們會(huì)被稱為GC(GarbageCollection)的垃圾回收機(jī)制收集。發(fā)生GC時(shí),JVM會(huì)從根對(duì)象開(kāi)始,一個(gè)個(gè)地檢查所相應(yīng)的存儲(chǔ)空間 運(yùn)行的某些階段,會(huì)導(dǎo)致應(yīng)用程序停止響應(yīng)其他請(qǐng)求,這種行為STW(StopTheWord暫停)。JVM調(diào)優(yōu)的重要目標(biāo)之一,就是最大程度地減少GC停的持續(xù)時(shí)間復(fù)習(xí)完JVM內(nèi)存管理機(jī)制,我們還要看一下與它相關(guān)的Linux的內(nèi)存管理機(jī)制在Linux操作系統(tǒng)上,虛擬內(nèi)存空間基本上是固定大?。ɡ?KB)的頁(yè)面。Linux近年Linux內(nèi)存管理有一個(gè)頁(yè)面回收的機(jī)制。它在內(nèi)部維護(hù)一個(gè)空閑頁(yè)面(FreePage)列表來(lái)滿足未來(lái)應(yīng)用程序的內(nèi)存請(qǐng)求。當(dāng)空閑頁(yè)面的數(shù)量下降到一定水平時(shí),操作系統(tǒng)就開(kāi)收頁(yè)面,并將新回收的頁(yè)面添加到空閑列表執(zhí)行頁(yè)面回收時(shí),操作系統(tǒng)需要進(jìn)行頁(yè)面掃描Scanning),以檢查已經(jīng)分配頁(yè)的活動(dòng)性。Linux有兩個(gè)策略來(lái)進(jìn)行頁(yè)面掃描:后臺(tái)掃描(由kswapd守護(hù)程序執(zhí)行)前臺(tái)掃描(由進(jìn)程自己執(zhí)行)通常情況下,后臺(tái)掃描就夠了,應(yīng)用程序的性能一般不會(huì)受到影響。但是當(dāng)操作系統(tǒng)的使用非常大,空閑頁(yè)面嚴(yán)重不足時(shí) 就會(huì)啟動(dòng)前臺(tái)頁(yè)面回收,也被稱為直接回收或步回收。在前臺(tái)頁(yè)面回收過(guò)程中,應(yīng)用程序會(huì)停止運(yùn)行,因此對(duì)應(yīng)用程序影響很Linux還有一個(gè)頁(yè)面交換(PageSwapping)的機(jī)制。是當(dāng)可用內(nèi)存不足時(shí),Linux會(huì)將某些內(nèi)存頁(yè)面換出到外部存儲(chǔ),以回收內(nèi)存空間來(lái)運(yùn)行新進(jìn)程。當(dāng)對(duì)應(yīng)于換出頁(yè)面的內(nèi)間,再次處于活動(dòng)狀態(tài)間,再次處于活動(dòng)狀態(tài)時(shí),系統(tǒng)會(huì)把這些頁(yè)面重新從外部存儲(chǔ)換入內(nèi)內(nèi)存管理方面,THP(TransparentHugePages,透明大頁(yè)面)是另外一個(gè)機(jī)制,也是了提高進(jìn)程的性能。我們 第22講討論過(guò),如果系統(tǒng)用較大的頁(yè)面,比如2MB,是傳統(tǒng)4KB,那么會(huì)帶來(lái)一些好處,尤其是所需的地址轉(zhuǎn)換條目數(shù)會(huì)減少盡管使用大頁(yè)面的好處很早就為人所理解,但在THP引入之前,程序想使用大型頁(yè)面容易。例如,操作系統(tǒng)啟動(dòng)時(shí),需要保留大頁(yè)面,并且進(jìn)程必須顯式調(diào)用才能分配大頁(yè)而THP就是為了避免這兩個(gè)問(wèn)題而設(shè)計(jì)的,因此操作系統(tǒng)默認(rèn)情況下就啟用THP我們先看應(yīng)用程序啟動(dòng)時(shí)的場(chǎng)景。當(dāng)幾個(gè)共存的應(yīng)用程序共享有限的計(jì)算資源(包括內(nèi)cpu)時(shí),它們之間會(huì)相互影響。如果各自獨(dú)立地運(yùn)行,導(dǎo)致對(duì)系統(tǒng)計(jì)算資源的消調(diào)一致,那么某些應(yīng)用程序會(huì)出現(xiàn)問(wèn)題這個(gè)實(shí)驗(yàn)采用了兩個(gè)相同的Java程序。我們首先啟動(dòng)第一個(gè)程序,來(lái)占用一些內(nèi)剩下約20GB的未使用內(nèi)存。然后我們開(kāi)始啟動(dòng)另外一個(gè)Java程序,這個(gè)程序需要的堆在圖中你可以看到,在圖中你可以看到,啟動(dòng)第二個(gè)程序之后,它的吞吐量是12K/秒,持續(xù)時(shí)間約30秒。后,吞吐量開(kāi)始急劇下降。最壞的情況,在大約20秒的時(shí)間內(nèi),吞吐量幾乎為零。有是,過(guò)了一會(huì)兒,吞吐量又再次回到了穩(wěn)定秒下圖顯示了同一時(shí)間段GC暫停信息最初的GC暫停很低,都低于50毫秒;然后暫停就跳到數(shù)百毫秒之大。你甚至可以次大于1秒的超大的暫停!大約1分鐘后,GC暫停再次下降至低于50毫秒,并變得定我們看到我們看到在啟動(dòng)期間,Java程序的性能很差。因?yàn)閱?wèn)題是在啟動(dòng)JVM時(shí)發(fā)生的,我們有由懷疑這與JVM的啟動(dòng)方式有關(guān)。我們檢查了程序的的內(nèi)存駐留大小Size),也就是進(jìn)程使用的未交換的物理內(nèi)存,圖示如從圖中你可以看到,盡管我們?cè)趩?dòng)JVM時(shí),用參數(shù)將JVM的堆大小指定為20GB(-Xmx20g和-Xms20g),但是JVM并不會(huì)從內(nèi)存中一次全部拿到20GB的堆空間。相反,操作系統(tǒng)會(huì)在JVM的運(yùn)行過(guò)程中不斷地分配。也就是說(shuō),隨著JVM實(shí)例化越來(lái)越多的對(duì)象,JVM會(huì)從操作系統(tǒng)逐漸拿到更多的內(nèi)存頁(yè)面來(lái)容納它們。在分配過(guò)程中,操作系統(tǒng)將不斷地檢查空閑頁(yè)面列表。如果發(fā)現(xiàn)可用內(nèi)存量低于一定水操作系統(tǒng)就會(huì)開(kāi)始回收頁(yè)面,這個(gè)過(guò)程會(huì)花費(fèi)CPU的時(shí)間。根據(jù)可用內(nèi)存短缺的嚴(yán)重程常低的水平下面這張圖顯示了CPU下面這張圖顯示了CPU的空閑百分比(CPU空閑百分比和繁忙百分比的和是100%)。比時(shí)間線,我們可以清楚地看到,頁(yè)面回收過(guò)程會(huì)導(dǎo)了開(kāi)銷,也就是空閑百那么怎么進(jìn)行內(nèi)存回收呢在Linux上,當(dāng)可用內(nèi)存不足時(shí),操作系統(tǒng)會(huì)喚kswapd守護(hù)程序,開(kāi)始在后臺(tái)回收閑頁(yè)面。如果內(nèi)存壓力很大,操作系統(tǒng)就會(huì)被迫采取另外一種措施,就是直接地同步釋放存的前臺(tái)。具體來(lái)講,當(dāng)可用空閑頁(yè)面降到一個(gè)閾值之下,就會(huì)觸發(fā)這種直接前 會(huì)凍結(jié)正在申請(qǐng)內(nèi)存的執(zhí)行代碼的應(yīng)用程序,從而間接地導(dǎo)致大量的GC暫停。此外,直接回收通常會(huì)掃描大量?jī)?nèi)存頁(yè)面,以釋放未使用的頁(yè)面。那么我們就來(lái)直接回收內(nèi)存頁(yè)面的繁忙程度。下圖就畫出通過(guò)直接回收路徑掃描的頁(yè)面數(shù)我們看到,在峰值時(shí),通過(guò)直接回收,每秒掃描約48K個(gè)頁(yè)面(即200MB);這個(gè)回收工作量是很大的,CPU會(huì)不堪重負(fù)。了解過(guò)程序啟動(dòng)時(shí)互相干擾的場(chǎng)景,我們?cè)賮?lái)考慮第二個(gè)場(chǎng)景:應(yīng)用程序在持續(xù)我們的實(shí)驗(yàn)是這樣進(jìn)行的。第一個(gè)Java程序以20GB的堆啟動(dòng),并進(jìn)入穩(wěn)定狀態(tài)。然后另外一個(gè)程序啟動(dòng),并開(kāi)始分配50GB的內(nèi)存。下圖中體現(xiàn)了第一個(gè)程序的吞吐從圖中我們看從圖中我們看到,第一個(gè)程序從一開(kāi)始就實(shí)現(xiàn)了穩(wěn)定的12K/秒的吞吐量。然后,吞吐量劇下降到零,這個(gè)零吞吐量的過(guò)程持續(xù)了約2分鐘。從那時(shí)起,吞吐量一直在發(fā)的變化:有時(shí)吞吐量是12K/秒,其他時(shí)候又我們也觀察JVM的暫停,用下圖所示 暫停幾乎為零,然后居然有一個(gè)超級(jí)大的暫停;多大呢?55秒!從那時(shí)起,GC暫停持續(xù)變化,但很少恢復(fù)為零。大多數(shù)暫停時(shí)間為幾秒鐘。我們觀察到,我們觀察到,其他應(yīng)用程序的運(yùn)行會(huì)嚴(yán)重影響本程序的性能。各種觀察的結(jié)論是,系統(tǒng)內(nèi)存壓力之下,操作系統(tǒng)內(nèi)存會(huì)有很多和外部存儲(chǔ)的頁(yè)面交換活動(dòng)。在下圖中,我們看作系統(tǒng)交換出了很多內(nèi)存頁(yè)面到外部存儲(chǔ)空這些換出的內(nèi)存頁(yè)面很多屬于Java程序(也就是堆空間)。JVM需要進(jìn)行堆上的圾回收,也就是GC,那么GC需要掃描JVM對(duì)象,以收集失效的對(duì)象。如果掃描的恰好是分配在換出的頁(yè)面上,那么JVM需要先將它們從外部存儲(chǔ)交換空間重新載中。從外部存儲(chǔ)載入內(nèi)存需要一些時(shí)間,因?yàn)榻粨Q空間通常位于磁盤驅(qū)所有這些時(shí)間,都會(huì)算在GC暫停之中。因此,程序會(huì)看到較大的GC暫停。下圖就顯示盡管頁(yè)面交換活動(dòng)會(huì)盡管頁(yè)面交換活動(dòng)會(huì)增加GC暫停時(shí)間,似乎可以解釋剛剛看到的JVM暫停。但是,我懷疑,僅是這個(gè)原因根本無(wú)法解釋生產(chǎn)中看到的很大暫停,比如超過(guò)55秒的暫停。你可能會(huì)問(wèn),我為什么有這樣的懷疑?因?yàn)槲以谠S多GC暫停的過(guò)程中,觀察到了較高的系統(tǒng)CPU比如在下圖中,我們觀察到,系統(tǒng)也處于嚴(yán)CPU壓力下CPU的高使用率不能完全歸因于頁(yè)面交換活動(dòng),因?yàn)轫?yè)面交換通常不會(huì)占用大CPU。以,其中“必有隱情”:一定是有其他活動(dòng)在大量使CPU。我們通過(guò)檢查了各能指標(biāo),最終確定了根能指標(biāo),最終確定了根因:是由于THP的機(jī)制,該機(jī)制嚴(yán)重加劇了程序性能和系統(tǒng)性能的具體來(lái)說(shuō),Linux啟用THP后,當(dāng)應(yīng)用程序分配內(nèi)存時(shí),會(huì)優(yōu)先選擇2MB大小的透明頁(yè)面,而不是4KB的常規(guī)頁(yè)面。這一點(diǎn)我們可以輕易驗(yàn)證,比如下圖中顯示了透的瞬時(shí)數(shù)量。在峰值時(shí),我們看到約34,000THP,即約68GB的內(nèi)存量我們還觀察到,THP的數(shù)量一開(kāi)始很高,一段時(shí)間后開(kāi)始下降。這是因?yàn)槟承㏕HP被拆分為什么需要拆分大頁(yè)面呢?是因?yàn)楫?dāng)Linux在有內(nèi)存壓力時(shí),它會(huì)將THP分為常規(guī)的、準(zhǔn)備交換的頁(yè)面。為什么必需拆分大頁(yè)面?這是因?yàn)楫?dāng)前交換Linux,僅支持常規(guī)大小頁(yè)拆分活動(dòng)的數(shù)量我們也用下圖畫出來(lái)了。你可以看到,在五分鐘內(nèi)大約有5K個(gè)THP頁(yè)面被拆分,對(duì)應(yīng)于10GB的內(nèi)存。除了大頁(yè)面拆分,同時(shí),Linux也會(huì)嘗除了大頁(yè)面拆分,同時(shí),Linux也會(huì)嘗試將常規(guī)頁(yè)面重新聚合為THP大頁(yè)面,這就需要外的頁(yè)面掃描,并消量CPUCPU。如果你在實(shí)踐中注意觀察的話,可以發(fā)現(xiàn)這種活動(dòng)使用THP可能遇到的更糟糕的情況是,聚合和拆分這兩個(gè)相互矛盾的活動(dòng),是來(lái)回執(zhí)行的。也就是說(shuō),當(dāng)系統(tǒng)承受內(nèi)存壓力時(shí),THP被拆分成常規(guī)頁(yè)面,而不久之后,常規(guī)頁(yè)則又被聚合應(yīng)用程序性能THP,依此類推。我們已經(jīng)觀察到,這種行為會(huì)嚴(yán)重?fù)p害我們生產(chǎn)我們的解決方案由三個(gè)設(shè)計(jì)元素組成,每個(gè)設(shè)計(jì)元素都針對(duì)問(wèn)題的特定方面。部署任何的元素都將在一定程度上對(duì)問(wèn)題有所幫助。但是,所有設(shè)計(jì)元素協(xié)同工作,才能獲得最效果第一個(gè)設(shè)計(jì)元素是預(yù)分配JVM的堆空間我們知道,對(duì)JVM而言,只有在實(shí)際使用堆空間之時(shí),就是當(dāng)需要增大堆空間來(lái)容納新對(duì)象分配請(qǐng)求時(shí) 才會(huì)為之分配新的內(nèi)存頁(yè)面,這時(shí)就可能會(huì)觸發(fā)大量頁(yè)面回收,并害程序和系統(tǒng)性這個(gè)設(shè)計(jì)元害程序和系統(tǒng)性這個(gè)設(shè)計(jì)元素就是預(yù)分配所有堆空間,從而避免了Linux實(shí)時(shí)分配頁(yè)面的不利場(chǎng)先執(zhí)行堆預(yù)分配,需要使用一個(gè)特殊的JVM參數(shù):“-XX:+AlwaysPreTouch”,來(lái)動(dòng)Java應(yīng)用程序但這個(gè)設(shè)計(jì)元素也有副作用,就是增加了JVM啟動(dòng)所需的時(shí)間,在部署時(shí)你需要點(diǎn)。我們也做過(guò)一些實(shí)際測(cè)量,這個(gè)額外啟動(dòng)時(shí)間并不大,一般在幾秒鐘內(nèi),通常是可受的第二個(gè)設(shè)計(jì)元素,是關(guān)于如何保護(hù)JVM的堆空間不被喚出到外部存儲(chǔ)我們知道,當(dāng)發(fā)生GC時(shí),JVM需要掃描相應(yīng)的內(nèi)存頁(yè)。如果這些頁(yè)面被操作系統(tǒng)換出到外部存儲(chǔ),則需要先換入它們到內(nèi)存,這就會(huì)導(dǎo)致延遲,會(huì)增加JVM的暫停時(shí)間。這個(gè)設(shè)計(jì)元素就可以防止JVM的堆頁(yè)面被換出。我們知道,nx操作系統(tǒng)上是可以關(guān)閉微調(diào)以頁(yè)面交換。例如,你可以使用group來(lái)精確控制要交換的應(yīng)用程序。公司中的大多數(shù)平臺(tái),一般都用來(lái)運(yùn)行同類Java應(yīng)用程序;這些程序往往配置差不多。在第三個(gè)設(shè)計(jì)元素是動(dòng)態(tài)調(diào)整THP我們已經(jīng)看到,啟用THP功能可能會(huì)在某些場(chǎng)景下,導(dǎo)致嚴(yán)重的性能損失;但是THP在其他場(chǎng)景的確提高了性能,所以到底是否要啟用THP呢?我們需要仔細(xì)考慮。當(dāng)THP影響性能時(shí),系統(tǒng)的可用內(nèi)存往往也恰好嚴(yán)重不足。發(fā)生這種情況時(shí),現(xiàn)有的需要拆分成常規(guī)頁(yè)面以進(jìn)行頁(yè)面換出。所以,我建議你用一個(gè)可用內(nèi)存大小的閾THP的開(kāi)關(guān)具體來(lái)說(shuō),就是建議你使用應(yīng)用程序的堆大小作為內(nèi)存閾值,來(lái)決定是否打開(kāi)或THP。當(dāng)可用內(nèi)存遠(yuǎn)遠(yuǎn)大于應(yīng)用程序的內(nèi)存可能占用量大小時(shí),就啟THP,因?yàn)橄到y(tǒng)太可能在啟動(dòng)特定應(yīng)太可能在啟動(dòng)特定應(yīng)用程序后出現(xiàn)內(nèi)存壓力。否則的話,就關(guān) THP此外,常規(guī)頁(yè)面需要聚合THP,才能將大頁(yè)面分配給應(yīng)用程序。因此,這個(gè)元一部分機(jī)制是進(jìn)行微調(diào),是決定何時(shí)允許THP聚合。我建議你根據(jù)操作系統(tǒng)的直接頁(yè)面描率和聚合進(jìn)程的CPU使用率來(lái)決常很有限,所以兩人只能常很有限,所以兩人只能用眼神傳達(dá)更復(fù)雜的情感。應(yīng)用程序之間的關(guān)系,甚至程序和系統(tǒng)及硬件之間的關(guān)系,也會(huì)很復(fù)雜,也需要做足夠的性能分析,才能理清它們系今天的講述,主要集中在多任務(wù)共存環(huán)境中的兩個(gè)問(wèn)題,重點(diǎn)在分析問(wèn)題產(chǎn)生的復(fù)雜根如果你對(duì)這方面的具體算法和生產(chǎn)驗(yàn)證有興趣,可

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論