1. 程式人生 > >Tomcat性能調優參數簡介

Tomcat性能調優參數簡介

info 分配 htm ble java.awt 無限 重新 查找 物理內存

近期,我們的一個項目進入了試運營的階段,在系統部署至阿裏雲之後,我們發現整個系統跑起來還是比較慢的,而且,由於代碼的各種不規範,以及一期進度十分趕的原因,缺少文檔和完整的測試,整個的上線過程一波三折。好了,不多說,切入正題,項目使用的是學校提供的阿裏雲,基於windows server,web容器tomcat8.0(開發的java版本是7,所以tomcat9.0不支持),通過網絡上和書籍上查找的相關資料,我們對tomcat的配置做了一些改變。

首先介紹一下服務詳細的環境信息:

(1)Windows Server 2008 R2 Enterprise 64位

(2)4GB 內存(操作系統占用2.3G內存)

(3)jdk 1.7 64位

(4)Tomcat 8.0解壓縮版

由於是在windows server下,因此我們改動的配置需要加在tomcat的bin目錄下的catalina.bat中。如果是linux系統下,則需修改catalina.sh文件。Tomcat的優化分為兩塊:

(1)Tomcat啟動命令行中的優化。(Tomcat啟動jvm時對jvm的參數配置優化)

(2)Tomcat容器自身參數的優化。

我們這裏主要針對的是Tomcat啟動命令的優化參數:

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

不慌,我們來看一下每一個參數都代表什麽意思,並且大致說明一下為什麽要配置這個參數。

(1)-server : 一般開發工具中使用的是client,針對不同的服務器使用的不同,jvm server比jvm client 更優化,jvm server 啟動較慢但啟動後運行速度較快。jvm client 啟動較快。jvm client 中能運行的可能在jvm server中運行出錯 ,所以這樣的話最好在開發、測試階段都使用jvm server ,保持和服務器相同。不過一直用client,也沒出現過什麽問題,服務器端用的是server的。可能這種高技術含量的bug相當不容易出現了。JVM Server模式與client模式啟動,最主要的差別在於:-Server模式啟動時,速度較慢,但是一旦運行起來後,性能將會有很大的提升。JVM如果不顯式指定是-Server模式還是-client模式。我們可以在命令行輸入java -help查看到-server這個命令。技術分享圖片

(2)-Xms1000M和-Xmx1000M:這兩個參數分別代表的是初始堆大小和最大堆大小。可以看到這兩個值設置的是相等的,是因為如果一個系統隨著並發數越來越高,它的內存使用情況逐步上升,直到達到最大內存大小,jvm就會進行垃圾回收,垃圾回收之後jvm就會重新分配內存,如果垃圾回收十分頻繁,那jvm就要不斷的去重新分配內存,這樣就會浪費性能,因此一開始我們就把這兩個設成一樣,使得Tomcat在啟動時就為最大化參數充分利用系統的效率,這個道理和jdbcconnection pool裏的minpool size與maxpool size的需要設成一個數量是一樣的原理。

(3)-Xss512k :設置每個線程的堆棧大小。JDK5.0以後每個線程堆棧大小為1M,以前每個線程堆棧大小為256K。更具應用的線程所需內存大小進行調整。在相同物理內存下,減小這個值能生成更多的線程。但是操作系統對一個進程內的線程數還是有限制的,不能無限生成,經驗值在3000~5000左右。這個選項對性能影響比較大,需要嚴格的測試。我們這裏為了保險起見用了512k。

(4) -XX:+AggressiveOpts :這個參數的意思是啟用這個參數,則每當JDK版本升級時,你的JVM都會使用最新加入的優化技術。

(5)-XX:+UseBiasedLocking:啟用一個優化了的線程鎖(偏向鎖),我們知道在tomcat中維護了一個線程池,每個http請求就是一個線程,線程多的時候就會有競爭的情況出現。這時候我們就需要鎖來控制多線程訪問競爭的資源,而這裏說的偏向鎖是JDK 1.6提出的一種鎖優化方式,起核心思想是如果程序沒有競爭,則取消之前已經取得鎖的線程的同步操作。也就是說,某一個鎖被一個線程獲取之後,便進入了偏向鎖模式,當該線程再次請求這個鎖時,就無需再進行相關的同步操作,從而節省了操作時間。但是如果在此期間,有其他線程申請了這個鎖,則退出偏向鎖模式。關於偏向鎖的原理,近期我會再發一篇博客好好的總結一下。

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

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

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

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

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

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

(12)-XX:+UseCMSCompactAtFullCollection:設置CMS 收集器在完成垃圾收集後是否要進行一次內存碎片整理。減少內存碎片。

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

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

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

(16)-Djava.awt.headless=true:在Java服務器程序需要進行部分圖像處理功能時,建議將程序運行模式設置為headless,這樣有助於服務器端有效控制程序運行狀態和內存使用(可防止在處理大圖片時發生內存溢出)。

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

註:以上部分內容來自於網絡

參考鏈接:http://www.cnblogs.com/redcreen/archive/2011/05/04/2037057.html#CMSInitiatingOccupancyFraction_value

http://ifeve.com/useful-jvm-flags-part-5-young-generation-garbage-collection/

https://segmentfault.com/a/1190000005174819

Tomcat性能調優參數簡介