學(xué)習(xí)筆記:Tomcat性能調(diào)優(yōu)參數(shù)簡介

近期,我們的一個(gè)項(xiàng)目進(jìn)入了試運(yùn)營的階段,在系統(tǒng)部署至阿里云之后,我們發(fā)現(xiàn)整個(gè)系統(tǒng)跑起來還是比較慢的,而且,由于代碼的各種不規(guī)范,以及一期進(jìn)度十分趕的原因,缺少文檔和完整的測(cè)試,整個(gè)的上線過程一波三折。好了,不多說,切入正題,項(xiàng)目使用的是學(xué)校提供的阿里云,基于windows server,web容器tomcat8.0(開發(fā)的java版本是7,所以tomcat9.0不支持),通過網(wǎng)絡(luò)上和書籍上查找的相關(guān)資料,我們對(duì)tomcat的配置做了一些改變。

? ?首先介紹一下服務(wù)詳細(xì)的環(huán)境信息:

? ? ? ?(1)Windows Server 2008 R2 Enterprise 64位

? ? ? ?(2)4GB 內(nèi)存(操作系統(tǒng)占用2.3G內(nèi)存)

? ? ? ?(3)jdk 1.7 64位

? ? ? ?(4)Tomcat 8.0解壓縮版

? ?由于是在windows server下,因此我們改動(dòng)的配置需要加在tomcat的bin目錄下的catalina.bat中。如果是linux系統(tǒng)下,則需修改catalina.sh文件。Tomcat的優(yōu)化分為兩塊:

? ? ? ?(1)Tomcat啟動(dòng)命令行中的優(yōu)化。(Tomcat啟動(dòng)jvm時(shí)對(duì)jvm的參數(shù)配置優(yōu)化)

? ? ? ?(2)Tomcat容器自身參數(shù)的優(yōu)化。

? ?我們這里主要針對(duì)的是Tomcat啟動(dòng)命令的優(yōu)化參數(shù):

? ?set JAVA_OPTS=? ? ? ? ? ? ? ? -server? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?-Xms1000M? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?-Xmx1000M

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -Xss512k? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?-XX:+AggressiveOpts? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?-XX:+UseBiasedLocking

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -XX:PermSize=128M? ? ? ? ? ? ? ? ? ? ? ? ? ? ?-XX:MaxPermSize=256M? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -XX:+DisableExplicitGC

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -XX:MaxTenuringThreshold=31? ? ? ? ? ? ? ?-XX:+UseConcMarkSweepGC? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?-XX:+UseParNewGC

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -XX:+CMSParallelRemarkEnabled? ? ? ? ? ?-XX:+UseCMSCompactAtFullCollection? ? ? ? ? ? ? ? ? ? ? -XX:LargePageSizeInBytes=128m

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -XX:+UseFastAccessorMethods? ? ? ? ? ? ?-XX:+UseCMSInitiatingOccupancyOnly? ? ? ? ? ? ? ? ? ? ? ?-Djava.awt.headless=true

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -XX:+HeapDumpOnOutOfMemoryError? ?-XX:HeapDumpPath=C:\apache-tomcat-7.0.42\webapps

? ?不慌,我們來看一下每一個(gè)參數(shù)都代表什么意思,并且大致說明一下為什么要配置這個(gè)參數(shù)。

(1)-server :?一般開發(fā)工具中使用的是client,針對(duì)不同的服務(wù)器使用的不同,jvm server比jvm client 更優(yōu)化,jvm server 啟動(dòng)較慢但啟動(dòng)后運(yùn)行速度較快。jvm client? 啟動(dòng)較快。jvm client 中能運(yùn)行的可能在jvm server中運(yùn)行出錯(cuò) ,所以這樣的話最好在開發(fā)、測(cè)試階段都使用jvm server ,保持和服務(wù)器相同。不過一直用client,也沒出現(xiàn)過什么問題,服務(wù)器端用的是server的??赡苓@種高技術(shù)含量的bug相當(dāng)不容易出現(xiàn)了。JVM Server模式與client模式啟動(dòng),最主要的差別在于:-Server模式啟動(dòng)時(shí),速度較慢,但是一旦運(yùn)行起來后,性能將會(huì)有很大的提升。JVM如果不顯式指定是-Server模式還是-client模式。我們可以在命令行輸入java -help查看到-server這個(gè)命令。

? ? ? ?(2)-Xms1000M和-Xmx1000M:這兩個(gè)參數(shù)分別代表的是初始堆大小和最大堆大小。可以看到這兩個(gè)值設(shè)置的是相等的,是因?yàn)槿绻粋€(gè)系統(tǒng)隨著并發(fā)數(shù)越來越高,它的內(nèi)存使用情況逐步上升,直到達(dá)到最大內(nèi)存大小,jvm就會(huì)進(jìn)行垃圾回收,垃圾回收之后jvm就會(huì)重新分配內(nèi)存,如果垃圾回收十分頻繁,那jvm就要不斷的去重新分配內(nèi)存,這樣就會(huì)浪費(fèi)性能,因此一開始我們就把這兩個(gè)設(shè)成一樣,使得Tomcat在啟動(dòng)時(shí)就為最大化參數(shù)充分利用系統(tǒng)的效率,這個(gè)道理和jdbcconnection pool里的minpool size與maxpool size的需要設(shè)成一個(gè)數(shù)量是一樣的原理。

? ? ? ?(3)-Xss512k :設(shè)置每個(gè)線程的堆棧大小。JDK5.0以后每個(gè)線程堆棧大小為1M,以前每個(gè)線程堆棧大小為256K。更具應(yīng)用的線程所需內(nèi)存大小進(jìn)行調(diào)整。在相同物理內(nèi)存下,減小這個(gè)值能生成更多的線程。但是操作系統(tǒng)對(duì)一個(gè)進(jìn)程內(nèi)的線程數(shù)還是有限制的,不能無限生成,經(jīng)驗(yàn)值在3000~5000左右。這個(gè)選項(xiàng)對(duì)性能影響比較大,需要嚴(yán)格的測(cè)試。我們這里為了保險(xiǎn)起見用了512k。

? ? ? ? (4) -XX:+AggressiveOpts :這個(gè)參數(shù)的意思是啟用這個(gè)參數(shù),則每當(dāng)JDK版本升級(jí)時(shí),你的JVM都會(huì)使用最新加入的優(yōu)化技術(shù)。

(5)-XX:+UseBiasedLocking:啟用一個(gè)優(yōu)化了的線程鎖(偏向鎖),我們知道在tomcat中維護(hù)了一個(gè)線程池,每個(gè)http請(qǐng)求就是一個(gè)線程,線程多的時(shí)候就會(huì)有競(jìng)爭(zhēng)的情況出現(xiàn)。這時(shí)候我們就需要鎖來控制多線程訪問競(jìng)爭(zhēng)的資源,而這里說的偏向鎖是JDK 1.6提出的一種鎖優(yōu)化方式,起核心思想是如果程序沒有競(jìng)爭(zhēng),則取消之前已經(jīng)取得鎖的線程的同步操作。也就是說,某一個(gè)鎖被一個(gè)線程獲取之后,便進(jìn)入了偏向鎖模式,當(dāng)該線程再次請(qǐng)求這個(gè)鎖時(shí),就無需再進(jìn)行相關(guān)的同步操作,從而節(jié)省了操作時(shí)間。但是如果在此期間,有其他線程申請(qǐng)了這個(gè)鎖,則退出偏向鎖模式。關(guān)于偏向鎖的原理,近期我會(huì)再發(fā)一篇博客好好的總結(jié)一下。

? ? ?(6)-XX:PermSize=128M和-XX:MaxPermSize=256M:表示設(shè)置初始持久代大小和最大永久代大小。事實(shí)上如果我們使用的是java8,那我們就需要配置的是元空間的參數(shù):MetaspaceSize和MaxMetaspaceSize這兩個(gè)參數(shù)。

? ? ?(7)-XX:+DisableExplicitGC:關(guān)閉代碼中的System.gc()。

(8)-XX:MaxTenuringThreshold=31:設(shè)置垃圾最大年齡(此參數(shù)只有在Serial?串行GC時(shí)有效)。我們知道新生代存在的唯一理由是優(yōu)化垃圾回收(GC)的性能。更具體說,把堆劃分為新生代和老年代有2個(gè)好處:簡化了新對(duì)象的分配(只在新生代分配內(nèi)存),可以更有效的清除不再需要的對(duì)象(即死對(duì)象)(新生代和老年代使用不同的GC算法)。設(shè)置這個(gè)值的大小需要我們根據(jù)本地的調(diào)試監(jiān)控來得到一個(gè)理想的值,不能隨意的設(shè)置,我們需要觀察一下情況:如果從年齡分布中發(fā)現(xiàn),有很多對(duì)象的年齡持續(xù)增長(增長到導(dǎo)致To區(qū)的使用率很高甚至爆滿),在到達(dá)老年代閥值之前。這表示 -XX:MaxTenuringThreshold 設(shè)置過大。也就是說, 如果 -XX:MaxTenuring Www.jjjThreshold 的值大于1,但是很多對(duì)象年齡從未大于1.應(yīng)該看下幸存區(qū)的目標(biāo)使用率。如果幸存區(qū)使用率從未到達(dá),這表示對(duì)象都被GC回收,這正是我們想要的。 如果幸存區(qū)使用率經(jīng)常達(dá)到,有些年齡超過1的對(duì)象被移動(dòng)到老年代中。這種情況,可以嘗試調(diào)整幸存區(qū)大小或增加MaxTenuringThreshold值的大小。

? ? ?(9)-XX:+UseConcMarkSweepGC :即CMS gc(適用于老年代垃圾回收),這一特性只有jdk1.5即后續(xù)版本才具有的功能,它使用的是gc估算觸發(fā)和heap占用觸發(fā)。我們知道頻頻繁的GC會(huì)造面JVM的大起大落從而影響到系統(tǒng)的效率,因此使用了CMS GC后可以在GC次數(shù)增多的情況下,每次GC的響應(yīng)時(shí)間卻很短,比如說使用了CMS GC后經(jīng)過jprofiler的觀察,GC被觸發(fā)次數(shù)非常多,而每次GC耗時(shí)僅為幾毫秒。

(10)-XX:+UseParNewGC:ParNew收集器是許多運(yùn)行在Server模式下的虛擬機(jī)中首選的新生代收集器。ParNew收集器其實(shí)就是Serial收集器的多線程版本,除了Serial收集器外,目前只有它能與CMS收集器配合工作。

? ? (11)-XX:+CMSParallelRemarkEnabled:降低cms垃圾收集在初始標(biāo)記和重新標(biāo)記階段(這兩個(gè)階段需要stop the world)的停頓。

? ? (12)-XX:+UseCMSCompactAtFullCollection:設(shè)置CMS 收集器在完成垃圾收集后是否要進(jìn)行一次內(nèi)存碎片整理。減少內(nèi)存碎片。

(13)-XX:LargePageSizeInBytes=128m:使用大的內(nèi)存分頁。CPU 是通過尋址來訪問內(nèi)存的。32 位 CPU 的尋址寬度是 0~0xFFFFFFFF ,計(jì)算后得到的大小是 4G,也就是說可支持的物理內(nèi)存最大是 4G。但在實(shí)踐過程中,碰到了這樣的問題,程序需要使用 4G 內(nèi)存,而可用物理內(nèi)存小于 4G,導(dǎo)致程序不得不降低內(nèi)存占用。為了解決此類問題,現(xiàn)代 CPU 引入了 MMU(Memory Management Unit 內(nèi)存管理單元)。MMU 的核心思想是利用虛擬地址替代物理地址,即 CPU 尋址時(shí)使用虛址,由 MMU 負(fù)責(zé)將虛址映射為物理地址。MMU 的引入,解決了對(duì)物理內(nèi)存的限制,對(duì)程序來說,就像自己在使用 4G 內(nèi)存一樣。內(nèi)存分頁 (Paging) 是在使用 MMU 的基礎(chǔ)上,提出的一種內(nèi)存管理機(jī)制。它將虛擬地址和物理地址按固定大?。?K)分割成頁 (page) 和頁幀 (page frame),并保證頁與頁幀的大小相同。這種機(jī)制,從數(shù)據(jù)結(jié)構(gòu)上,保證了訪問內(nèi)存的高效,并使 OS 能支持非連續(xù)性的內(nèi)存分配。在程序內(nèi)存不夠用時(shí),還可以將不常用的物理內(nèi)存頁轉(zhuǎn)移到其他存儲(chǔ)設(shè)備上,比如磁盤,這就是大家耳熟能詳?shù)奶摂M內(nèi)存。使用大的內(nèi)存分頁可以增強(qiáng) CPU 的內(nèi)存尋址能力,從而提升系統(tǒng)的性能。

??(14)-XX:+UseFastAccessorMethods :原始類型的快速優(yōu)化。

(15)-XX:+UseCMSInitiatingOccupancyOnly:指示只有在老年代在使用了初始化的比例后,cms啟動(dòng)垃圾收集。

? ?(16)-Djava.awt.headless=true:在Java服務(wù)器程序需要進(jìn)行部分圖像處理功能時(shí),建議將程序運(yùn)行模式設(shè)置為headless,這樣有助于服務(wù)器端有效控制程序運(yùn)行狀態(tài)和內(nèi)存使用(可防止在處理大圖片時(shí)發(fā)生內(nèi)存溢出)。

? ?(17)?-XX:+HeapDumpOnOutOfMemoryError? ?-XX:HeapDumpPath=C:\apache-tomcat-7.0.42\webapps:配置了發(fā)生oom的時(shí)候dump線程至指定目錄。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容