Tomcat配置優化,主要在於優化tomcat運行模式,併發參數和線程數, 以及jvm堆內存和垃圾回收相關參數的優化.下面將逐一介紹.javascript
BIO: 同步阻塞IO, 性能低, 沒有通過任何優化處理和支持.
服務器實現模式爲一個鏈接一個線程. 即, 客戶端有鏈接請求時, 服務器端就須要啓動一個線程進行處理. 若是這個鏈接不作任何事情會形成沒必要要的線程開銷, 固然能夠經過 線程池 機制改善.
適用場景: BIO方式適用於鏈接數比較小且固定的架構, 這種方式對服務器資源要求比較高, 有併發侷限, JDK1.4以前的惟一選擇.css
NIO 是 Java SE 1.4 及後續版本提供的一種新的IO操做方式(即java.nio包及其子包).
Java NIO是一個基於緩衝區、並能提供非阻塞IO操做的Java API, 所以NIO也被當作是non-blocking IO(非阻塞式IO)的縮寫, 它擁有比傳統BIO操做更好的併發性能.
服務器實現模式爲一個請求一個線程, 即客戶端發送的鏈接請求都會註冊到多路複用器上, 多路複用器輪詢到鏈接有IO請求時才啓動一個線程進行處理.html
適用場景: 適用於鏈接數較多且鏈接比較時間短(輕操做)的架構, 好比聊天服務器. 這種方式的併發性能侷限於應用中, 編程比較複雜.
Tomcat 8.x默認運行在NIO模式下.java
APR(Apache Portable Runtime, Apache可移植運行時), 是Apache HTTP服務器的一個支持庫, 它提供了一組映射到底層操做系統的API, 若是操做系統不支持特定功能, APR庫將提供仿真. 所以開發人員可使用APR使程序真正跨平臺移植.
此模式的安裝步驟比較繁瑣, 但卻從操做系統層面解決了異步IO的問題, 能大幅度提升應用性能.
APR的本質是使用 JNI 技術調用操做系統底層的IO接口, 因此須要提早安裝必要的依賴, 具體配置方法見下文描述.web
BIO | NIO | NIO2 | APR | |
---|---|---|---|---|
類名 | Http11Protocol | Http11NioProtocol | Http11Nio2Protocol | Http11AprProtocol |
引用版本 | ≥3.0 | ≥6.0 | ≥8.0 | ≥5.5 |
輪詢支持 | 是 | 是 | 是 | |
輪詢隊列大小 | N/A | maxConnections | maxConnections | maxConnections |
讀請求頭 | 阻塞 | 非阻塞 | 非阻塞 | 阻塞 |
讀請求體 | 阻塞 | 阻塞 | 阻塞 | 阻塞 |
寫響應 | 阻塞 | 阻塞 | 阻塞 | 阻塞 |
等待新請求 | 阻塞 | 非阻塞 | 非阻塞 | 非阻塞 |
SSL支持 | Java SSL | Java SSL | Java SSL | Open SSL |
SSL握手 | 阻塞 | 非阻塞 | 非阻塞 | 阻塞 |
最大連接數 | maxConnections | maxConnections | maxConnections | maxConnections |
推薦使用nio,在tomcat8中有最新的nio2,速度更快,建議使用nio2apache
設置nio2:編程
<Connector executor="tomcatThreadPool" port="8080" protocol="org.apache.coyote.http11.Http11Nio2Protocol" connectionTimeout="20000" redirectPort="8443" />
Tomcat的Connector是其接收HTTP請求的關鍵模塊, 能夠經過它來指定IO處理模式, 指定處理該Connector接收到的請求的線程數, 以及其餘經常使用的HTTP策略.
配置路徑: 在 ${TOMCAT_HOME}/conf/server.xml 文件的節點中進行配置.數組
使用線程池, 經過較少的線程資源來處理更多的請求, 從而提升Tomcat的請求處理能力.
前提: 要提早配置至少一個線程池來處理請求, 配置文件爲${TOMCAT_HOME}/conf/server.xml.
其中Executor與Connector同級, 多個Connector可使用同一個線程池來處理請求.瀏覽器
1) 參考默認鏈接池配置:緩存
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="150" minSpareThreads="4"/>
2) 自定義線程池示例:
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="200" minSpareThreads="10" maxIdleTime="600000" prestartminSpareThreads="true" maxQueueSize="100" />
3) 線程池參數說明:
name: 線程池名稱.
namePrefix: 建立的每一個線程的名稱前綴, 單獨的線程名稱爲 namePrefix + threadNumber.
maxThreads: 線程池中最大併發線程數, 默認值爲200, 通常建議設置400~ 800 , 要根據服務器配置和業務需求而定. minSpareThreads: 最小活躍線程數, 也就是核心線程數, 不會被銷燬, 會一直存在. prestartminSpareThreads: 是否在啓動程序時就生成minSpareThreads個線程, 默認爲false, 即不啓動. 若不設置爲true, 則minSpareThreads的設置就不起做用了. maxIdleTime: 線程最大空閒時間, 超過該時間後, 空閒線程會被銷燬, 默認值爲6000, 單位爲毫秒.
maxQueueSize: 最大的等待隊列數, 超過則拒絕請求. 默認值爲int類型的最大值(Integer.MAX_VALUE), 等同於無限大. 通常不做修改, 避免發生部分請求未能被處理的狀況. threadPriority: 線程池中線程的優先級, 默認值爲5, 取值範圍: 1 ~ 10.
className:線程池的實現類, 未指定狀況下, 默認實現類爲 org.apache.catalina.core.StandardThreadExecutor. 要自定義線程池就須要實現 org.apache.catalina.Executor 接口.
Connector是Tomcat接收請求的入口, 每一個Connector都有本身專屬的監聽端口.
<Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
1) Connector的參數說明:
redirectPort="8443" # 基於SSL的端口, 在須要基於安全通道的場合, 好比當客戶端的請求協議是HTTPS時, 將該請求轉發到此端口.
minSpareThreads="25" # Tomcat鏈接器的最小空閒Socket線程數, 默認值爲25. 若是當前沒有空閒線程, 且沒有超過maxThreads, 將一次性建立的空閒線程數量. Tomcat初始化時建立的線程數量也是此值.
maxSpareThreads="75" # 最大空閒線程數, 一旦建立的線程超過此值, Tomcat就會關閉再也不須要的Socket線程, 默認值爲50. 線程數能夠大體用 "同時在線用戶數、用戶每秒操做次數、系統平均操做時間" 來計算.
keepAliveTimeout="6000" # 下次請求到來以前, Tomcat保持該鏈接6000ms.
maxKeepAliveRequests="10" # 該鏈接最大支持的請求數, 超過該請求數的鏈接也將被關閉(此時就會返回一個Connection: close頭給客戶端). 1表示禁用長鏈接, -1表示不限制鏈接個數, 默認爲100, 通常設置在100~200之間.
acceptorThreadCount="1" # 用於接收鏈接的線程的數量, 默認值是1. 通常若是服務器是多核CPU時, 須要改配置爲 2.
enableLookups="false" # 是否支持反查域名(即DNS解析), 默認爲true. 爲提升處理能力, 應設置爲false.
disableUploadTimeout="true" # 上傳時是否啓用超時機制, 若爲true, 則禁用上傳超時.
connectionTimeout="20000" # 網絡鏈接超時時間, 默認值爲20000ms, 設置爲0表示永不超時 —— 存在隱患. 一般可設置爲30000ms.
URIEncoding="UTF-8" # 指定Tomcat容器的URL編碼格式.
maxHttpHeaderSize="8192" # HTTP請求頭信息的最大程度, 超過此長度的部分不予處理. 通常設置爲8K便可.
maxPostSize="10485760" # 指定POST請求的內容大小, 單位爲Byte, 默認大小爲2097152(2MB), 10485760爲10M. 若是要禁用限制, 可設置爲-1.
compression="on" # 打開傳輸時壓縮功能.
compressionMinSize="10240" # 啓用壓縮的輸出內容大小, 默認爲2048, 即2KB.
noCompressionUserAgents="gozilla, traviata" # 設置不啓用壓縮的瀏覽器
compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain" # 壓縮的資源類型
2) 補充說明:
1>. Tomcat 的壓縮是在客戶端請求服務器對應資源後, 從服務器端將資源文件壓縮, 再輸出到客戶端, 由客戶端的瀏覽器負責解壓縮並瀏覽. 相對於普通的瀏覽過程(如瀏覽HTML、CSS、Javascript和Text), 它能夠節省40%左右的流量. 更爲重要的是, 它也能夠對動態生成的網頁(包括CGI、PHP、JSP、ASP、Servlet、SHTML等)進行壓縮. 2>. 須要注意的是, 壓縮會增長Tomcat的負擔, 最好採用 Nginx + Tomcat 或 Apache + Tomcat 方式, 將壓縮交由 Nginx / Apache 去完成. 在server.xml的節點配置(還沒有驗證使用):
1) 默認配置 - BlockingIO模型:
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
2) 關於NIO的說明:
org.apache.coyote.http11.Http11Nio2Protocol
更優.org.apache.coyote.http11.Http11NioProtocol
更優.3) NIO模型配置:
<Connector executor="tomcatThreadPool" port="8080" protocol="org.apache.coyote.http11.Http11Nio2Protocol" connectionTimeout="20000" redirectPort="8443" maxPostSize="10485760" acceptorThreadCount="2" />
4) 參數說明:
executor="..." # 鏈接器使用的線程池名稱.
port="..." # 鏈接端口, URL中指定此端口進行訪問.
protocol="..." # 鏈接器使用的請求處理模式.
redirectPort="8443" # 基於SSL的端口, 在須要基於安全通道的場合, 好比當客戶端的請求協議是HTTPS時, 將該請求轉發到此8443端口.
能夠簡單地將APR模式理解爲,Tomcat將以JNI的形式調用Apache HTTP服務器的核心動態連接庫, 進行文件讀取或網絡傳輸操做, 從而大大地提升Tomcat對靜態文件的處理性能.
APR是Tomcat上運行高併發應用的首選模式, 同時若是使用HTTPS方式傳輸, 也能夠提高SSL的處理性能.
前面已經提到, APR模式會調用操做系統底層的IO接口, 因此須要安裝必要的依賴.
1) 安裝OpenSSL:
安裝命令以下:
yum -y install openssl-devel
2) 安裝APR組件:
源碼安裝常見錯誤及解決:
可能出現gcc依賴沒有安裝的錯誤, 可經過 yum install gcc 命令安裝.
若是make過程當中出錯, 解決錯誤後從新安裝前須要執行清理: make clean, 而後再次嘗試make及make install過程.
若是拋出 xml/apr_xml.c:35:19: error: expat.h: No such file or directory, 說明缺乏了expat庫, 可執行下屬命令安裝: yum install expat-devel.
3) 安裝tomcat-native組件:
tomcat-native組件能夠看做是Tomcat與APR交互的中間環節.
tomcat-native?是什麼?前面沒有叫下載啊?
確實,我剛開始在網上搜索的時候也是很困惑的,但是有一我的說了,「就在下載的tomcat的bin目錄下面」,我去看了一下,果真有!!
將咱們安裝好的tomcat的bin目錄下的 tomcat-native.tar.gz 文件複製到 /usr/local/src 中,而且解壓縮,獲得目錄tomcat-native-<version>-src 在這個目錄中有相關的說明,告訴咱們如何構建。
進入到目錄中的 jni/native 目錄內,這個目錄內的文件就是咱們須要的文件,依次執行下面的命令
./configure --with-apr=/usr/local/apr --with-java-home=/usr/java/jdk --with-ssl=yes
make
make install
在這裏,apr的目錄要使用前面安裝apr的時候的目錄,若是修改了的話,還請對應修改,java的目錄要使用jdk的根目錄,若是不是這個也請修改。
執行上面的命令以後,會在目錄
/usr/local/apr/lib
中生成對應的文件,能夠查看文件,確認安裝成功。也能夠根據每一步執行命令的輸出來判斷成功沒有,如有問題的話,要及時解決,在進行後續操做。
4) Tomcat整合APR:
第一步: 修改啓動腳本catalina.sh
:
在${TOMCAT_HOME}/bin/catalina.sh
文件的 cygwin=false
前(110行左右)加入下述啓動參數:
JAVA_OPTS="$JAVA_OPTS -Djava.library.path=/usr/local/apr/lib"
第二步: 修改容器配置文件server.xml:
查看 ${TOMCAT_HOME}/conf/server.xml
文件, 確保以下監聽器沒有被註釋掉:
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
修改Connector選項:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol" maxThreads="150" SSLEnabled="true" > </Connector>
5) 驗證配置是否成功:
啓動Tomcat, 在 ${TOMCAT_HOME}/logs/catalina.out
文件中查看日誌信息:
若是出現下述內容, 說明APR組件安裝不成功:
Sep 14, 2018 19:11:20 PM org.apache.catalina.core.AprLifecycleListener init INFO: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path:...
若是出現下述內容, 說明APR組件安裝成功:
Sep 14, 2018 19:19:47 PM org.apache.catalina.core.AprLifecycleListener init INFO: Loaded APR based Apache Tomcat Native library 1.1.27 using APR version 1.6.3. Sep 14, 2018 19:19:47 PM org.apache.catalina.core.AprLifecycleListener init INFO: APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true]. Sep 14, 2018 19:19:47 PM org.apache.catalina.core.AprLifecycleListener initializeSSL INFO: OpenSSL successfully initialized (OpenSSL 1.0.1e-fips 11 Feb 2013) Sep 14, 2018 19:19:47 PM org.apache.coyote.AbstractProtocol init INFO: Initializing ProtocolHandler ["http-apr-8080"] Sep 14, 2018 19:19:47 PM org.apache.coyote.AbstractProtocol init INFO: Initializing ProtocolHandler ["ajp-apr-8009"]
Tomcat經過APR模式成功啓動:
Sep 14, 2018 19:19:56 PM org.apache.coyote.AbstractProtocol start INFO: Starting ProtocolHandler ["http-apr-8986"] Sep 14, 2018 19:19:56 PM org.apache.coyote.AbstractProtocol start INFO: Starting ProtocolHandler ["ajp-apr-8915"] Sep 14, 2018 19:19:56 PM org.apache.catalina.startup.Catalina start INFO: Server startup in 9421 ms
AJP(Apache JServer Protocol)是爲 Tomcat 與 HTTP 服務器之間通訊而定製的協議, 能提供較高的通訊速度和效率.
AJP v13 協議是面向包的, Web服務器和Servlet容器經過TCP鏈接來交互, 爲了節省 建立Socket的昂貴代價, Web服務器會嘗試維護一個永久的TCP鏈接到Servlet容器, 並在多個請求與響應週期過程內重用該TCP鏈接.
若是使用Apache架構, 就要用AJP鏈接器, 當Apache接收到動態網頁請求時, 經過在配置中指定的端口號將請求發送給在此端口號上監聽的AJP鏈接器組件.
若是不使用Tomcat + Apache, 而是用其餘架構, 如Tomcat + Nginx, 就須要註銷掉該鏈接器.
<!-- <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> -->
在Linux環境下設置Tomcat JVM,在/opt/tomcat/bin/catalina.sh文件中找到"
# ----- Execute The Requested Command"位置,設置JVM以下: # ----- Execute The Requested Command ----------------------------------------- JAVA_OPTS="$JAVA_OPTS -server -Xms3072m -Xmx3072m -XX:PermSize=1024M -XX:MaxPermSize=1024M"
參數說明:
-Xms:設置JVM最小內存。此值能夠設置與-Xmx相同,以免每次垃圾回收完成後JVM從新分配內存。
-Xmx:設置JVM最大可用內存。
-XX:NewSize:設置年輕代大小
-XX:PermSize:設置永久代大小
-XX:MaxPermSize:設置最大永久代大小
JVM內存模型
一、Java棧
Java棧是與每個線程關聯的,JVM在建立每個線程的時候,會分配必定的棧空間給線程。
它主要用來存儲線程執行過程當中的局部變量,方法的返回值,以及方法調用上下文。棧空間隨着線程的終止而釋放。
StackOverflowError:若是在線程執行的過程當中,棧空間不夠用,那麼JVM就會拋出此異常,這種狀況通常是死遞歸形成的。
二、堆
Java中堆是由全部的線程共享的一塊內存區域,堆用來保存各類JAVA對象,好比數組,線程對象等。
三、Java 的內存模型
a、Young,年輕代(易被 GC)
Young 區被劃分爲三部分,Eden 區和兩個大小嚴格相同的 Survivor 區
其中 Survivor 區間中,某一時刻只有其中一個是被使用的,另一個留作垃圾收集時複製對象用,在 Young 區間變滿的時候,minor GC 就會將存活的對象移到空閒的Survivor 區間中,根據 JVM 的策略,在通過幾回垃圾收集後,任然存活於 Survivor 的對象將被移動到 Tenured 區間。
b、Tenured,終身代
Tenured 區主要保存生命週期長的對象,通常是一些老的對象,當一些對象在 Young 複製轉移必定的次數之後,對象就會被轉移到 Tenured 區,通常若是系統中用了 application 級別的緩存,緩存中的對象每每會被轉移到這一區間。
c、Perm,永久代
主要保存 class,method,filed 對象,這部門的空間通常不會溢出,除非一次性加載了不少的類,不過在涉及到熱部署的應用服務器的時候,有時候會遇到 java.lang.OutOfMemoryError : PermGen space 的錯誤,形成這個錯誤的很大緣由就有多是每次都從新部署,可是從新部署後,類的 class 沒有被卸載掉,這樣就形成了大量的 class 對象保存在了 perm 中,這種狀況下,通常從新啓動應用服務器能夠解決問題。
若是服務器只運行一個 Tomcat:
機子內存若是是 8G,通常 PermSize 配置是主要保證系統能穩定起來就行:
JAVA_OPTS="-Dfile.encoding=UTF-8 -server -Xms6144m -Xmx6144m -XX:NewSize=1024m -XX:MaxNewSize=2048m -XX:MaxTenuringThreshold=10 -XX:NewRatio=2 -XX:+DisableExplicitGC"
機子內存若是是 16G,通常 PermSize 配置是主要保證系統能穩定起來就行:
JAVA_OPTS="-Dfile.encoding=UTF-8 -server -Xms13312m -Xmx13312m -XX:NewSize=3072m -XX:MaxNewSize=4096m -XX:MaxTenuringThreshold=10 -XX:NewRatio=2 -XX:+DisableExplicitGC"
機子內存若是是 32G,通常 PermSize 配置是主要保證系統能穩定起來就行:
JAVA_OPTS="-Dfile.encoding=UTF-8 -server -Xms29696m -Xmx29696m -XX:NewSize=6144m -XX:MaxNewSize=9216m -XX:MaxTenuringThreshold=10 -XX:NewRatio=2 -XX:+DisableExplicitGC"
若是是開發機:
-Xms550m -Xmx1250m -XX:PermSize=550m -XX:MaxPermSize=1250m
參數說明:
-Dfile.encoding:默認文件編碼
-server:表示這是應用於服務器的配置,JVM 內部會有特殊處理的
-Xmx1024m:設置JVM最大可用內存爲1024MB
-Xms1024m:設置JVM最小內存爲1024m。此值能夠設置與-Xmx相同,以免每次垃圾回收完成後JVM從新分配內存。
-XX:NewSize:設置年輕代大小
-XX:MaxNewSize:設置最大的年輕代大小
-XX:PermSize:設置永久代大小
-XX:MaxPermSize:設置最大永久代大小
-XX:NewRatio=4:設置年輕代(包括 Eden 和兩個 Survivor 區)與終身代的比值(除去永久代)。設置爲 4,則年輕代與終身代所佔比值爲 1:4,年輕代佔整個堆棧的 1/5
-XX:MaxTenuringThreshold=10:設置垃圾最大年齡,默認爲:15。若是設置爲 0 的話,則年輕代對象不通過 Survivor 區,直接進入年老代。對於年老代比較多的應用,能夠提升效率。若是將此值設置爲一個較大值,則年輕代對象會在 Survivor 區進行屢次複製,這樣能夠增長對象再年輕代的存活時間,增長在年輕代即被回收的概論。
-XX:+DisableExplicitGC:這個將會忽略手動調用 GC 的代碼使得 System.gc() 的調用就會變成一個空調用,徹底不會觸發任何 GC
Tomcat容器是運行在JVM上的, 其默認內存通常都很小(物理內存的1/64), 在實際生產環境中, 若不配置則會極大浪費服務器資源, 影像系統的性能. 能夠經過調整JVM啓動參數, 使得Tomcat擁有更好的性能.
對於JVM的優化主要有兩個方面: JVM內存調優 和 垃圾收集策略調優
Tomcat運行內存 = Xmx(初始內存大小) + Perm Generation(JDK 7中的永久代大小) + Java應用建立的線程數 * 1MB.
Java 應用每建立一個線程, JVM 進程的內存中就會建立一個 Thread 對象, 同時也會在操做系統中建立一個真正的物理線程(參考JVM規範), 操做系統會在 Tomcat 的空閒內存中建立這個物理線程, 而不是在 JVM 的 Xmx 堆內存中建立.
在 JDK 1.4中, 默認的棧大小是256KB/線程, 但自 JDK 5(爲了推廣的方便, JDK 後續版本再也不是1.x命名)開始, 默認的棧大小變爲1M/線程. 舉例: 若是系統剩餘內存爲400M, 則Java應用最多能建立400個可用線程.
因此: 要想建立更多的線程, 必須減小分配給JVM的最大內存.
內存配置相關參數:
注意:
① 若是不指定Xmx、Xms和NewSize、OldSize, 則系統將基於Xms=1/64總內存大小, 對各個Space按照NewRatio=2進行空間的分配, 此時NewSize與OldSize的默認大小將失效.
② 若是指定了Xmx、Xms, 未指定NewSize、OldSize, 則系統將優先知足 NewRatio=2, 且OldSize+NewSize=Xms, 此時NewSize與OldSize的默認大小將失效.
結論: 除非顯式指定NewSize與OldSize的值, 不然它們的默認配置通常都不會獲得知足. 顯式指定其中任一個, 另外一個就會基於默認值, 並根據應用程序的消耗動態分配空間大小.
JVM內存方面的調優, 須要在${TOMCAT_HOME}/bin/catalina.sh文件中調整, 配置 JAVA_OPTS 變量便可. 在啓動Tomcat時, 會執行catalina.sh中的腳本, 將 JAVA_OPTS 做爲JVM的啓動參數進行處理.
具體可參考以下配置(示例服務器配置: 126g的物理內存, 2個10核心20線程的物理CPU):
在文件最前面(即cygwin=false以前)設置, $JAVA_OPTS 的做用是保留原有的設置, 防止這次修改覆蓋以前的設置
JAVA_OPTS="$JAVA_OPTS -Xmx96g -Xms96g -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m"
1) 說明:
① 若不指定Xmx, 即Java Heap的最大值, 程序啓動時, JVM會調整其大小以知足程序運行的須要. 每次調整時, 都會對堆進行一次徹底垃圾收集(即Full GC), 比較影響性能. 所以推薦明確指定Xmx的大小.
② 令Xmx=Xms會有更好地性能表現: 能避免JVM在每次垃圾收集後從新動態調節堆空間, 由於頻繁伸縮堆大小將帶來額外的性能消耗.
③ JVM有2種模式: client客戶端模式 和 server服務端模式 , 平時開發中使用的可能是默認的client模式. 可經過命令行參數-server強制開啓server模式. 二者之間的最大區別是, JVM對server模式作了大量優化: 雖然server模式下應用程序啓動較慢, 但在長時間運行下, 程序運行效率會明顯高於client模式, 即 client模式不適合須要長時間運行的項目 .
2) 元空間的調優:
元空間的大小將受限於機器的內存的限制. 限制類的元數據的內存大小, 以免出現虛擬內存切換以及本地內存分配失敗.
若是可能出現類加載器泄漏, 應當配置此參數指定大小. 32位機器上, 若是地址空間可能會被耗盡, 也應當配置此參數.
元空間的初始大小是21M——這是GC的初始高水位線, 超過這個大小會進行Full GC來進行類的收集.
若是啓動後GC過於頻繁, 請將該值設置得大一些, 以便推遲GC的執行時間.
Tomcat的GC策略通常都是與其內存參數一塊兒配置的, 與應用複雜度相匹配的GC策略、與服務器性能相適應的內存比例, 都將使得系統性能獲得大幅提高.
GC策略方面的調優, 也是在 ${TOMCAT_HOME}/bin/catalina.sh文件中調整 -- 一樣是配置 JAVA_OPTS 變量便可.
JAVA_OPTS="$JAVA_OPTS -Xmx3550m -Xms3550m -Xss128k -XX:+UseParallelGC -XX:MaxGCPauseMillis=100"
參數說明:
# 並行收集器(吞吐量優先) java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:MaxGCPauseMillis=100 # 併發收集器(響應時間優先) java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseConcMarkSweepGC
參數說明:
以JDK 八、Tomcat 8爲例, 服務器內存爲128GB, 做出以下配置:
經過Solr集羣大批量導入數據的應用中, Parallel GC策略的暫停時間太長, 因此選擇CMS收集器.
# 下述配置各自獨佔一行, 要置於"cygwin=false"以前. # 配置內存 JAVA_OPTS="-server -Xmx96g -Xms96g -Xmn35g -XX:OldSize=55g -Xss128k -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m" # 配置GC策略 JAVA_OPTS="$JAVA_OPTS -XX:+UseConcMarkSweepGC -XX:MaxTenuringThreshold=15 -XX:CMSInitiatingOccupancyFraction=40 -XX:CMSFullGCsBeforeCompaction=0 -XX:+ExplicitGCInvokesConcurrent -XX:SoftRefLRUPolicyMSPerMB=0 -XX:MaxGCPauseMillis=100 -Xnoclassgc"
其中Java Heap的初始大小和最大大小均設置爲96g, 76%的物理內存(以不超過80%爲宜).
小結:
在內存設置中須要作一下權衡 1)內存越大,通常狀況下處理的效率也越高,但同時在作垃圾回收的時候所須要的時間也就越長,在這段時間內的處理效率是必然要受影響的。 2)在大多數的網絡文章中都推薦 Xmx和Xms設置爲一致,說是避免頻繁的回收,這個在測試的時候沒有看到明顯的效果,內存的佔用狀況基本都是鋸齒狀的效果,因此這個還要根據實際狀況來定。