最困難的事情就是認識本身!
我的網站,歡迎訪問!
Tomcat做爲Web應用的服務器,目前絕大多數公司都是用其做爲應用服務器的;應用服務器的執行效率會影響系統執行,這裏會講Tomcat怎樣進行配置能提升處理性能;除此以外也必然會提到對應的JVM參數的優化的一些經驗。
本文爲 轉載文章 ,原文地址:系統優化怎麼作-Tomcat優化java
運行模式分3種模式:git
- bio:默認的模式,效率比較低
- nio:優化時使用的模式
- apr:對系統配置有一些比較高的要求
查找配置文件 server.xml , 在tomcat下的路徑:conf 目錄下;Executor 爲自定義配置 Tomcat 線程池:程序員
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="1024" minSpareThreads="512" prestartminSpareThreads="true" />
最大線程數,默認是200
最小活躍線程數,默認是25
最大的等待隊列個數,超過則請求拒絕默認值是Integer.MAX_VALUE ,通常不改變。在某些緊急狀態修復問題須要調整
Connector是鏈接器,負責接收客戶的請求,以及向客戶端回送響應的消息。因此Connector的優化是重要部分。默認狀況下 Tomcat只支持200線程訪問,超過這個數量的鏈接將被等待甚至超時放棄,因此咱們須要提升這方面的處理能力。
配置文件 server.xml
<!-- 運行模式爲 nio --> <Connector port="14081" protocol="org.apache.coyote.http11.Http11NioProtocol" connectionTimeout="20000" <!-- 鏈接器中鏈接處理 使用上面自定義的 線程池中的線程 --> executor="tomcatThreadPool" URIEncoding="UTF-8" compression="on" useBodyEncodingForURI="true" enableLookups="false" redirectPort="14443" />
org.apache.coyote.http11.Http11Protocol - 阻塞式的Java鏈接器
org.apache.coyote.http11.Http11NioProtocol - 不阻塞Java鏈接器
org.apache.coyote.http11.Http11AprProtocol - APR / native 鏈接器
選擇不阻塞Java鏈接器
如果你想request.getRemoteHost()的調用履行,以便返回的長途客戶端的實際主機名的DNS查詢,則設置爲true。設置爲false時跳過DNS查找,並返回字符串的IP地址(從而提升性能)。 默認場景下,禁用DNS查找 。
設置成on,開啓壓縮
使用Nginx+tomcat的架構,用不着AJP協議,因此把AJP鏈接器禁用
server.xml註釋掉如下配置:github
<Connector port="8019" protocol="AJP/1.3" redirectPort="8443" />
優化位置:/bin/catalina.sh修改 JAVA_OPTS 參數,這裏須要參照 機器配置 ,對JVM進行參數優化 。算法
JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms512m -Xmx1024m -XX:NewSize=512m -XX:MaxNewSize=1024M -XX:PermSize=1024m -XX:MaxPermSize=1024m -XX:+DisableExplicitGC"
JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms1024m -Xmx1024m -XX:NewSize=512m -XX:MaxNewSize=1024M -XX:+DisableExplicitGC"
注意:1.8 中已經沒有 永久代了,因此也就沒有 沒有PermSize、MaxPermSize ;Java8 中將永久代改成了 元空間 了,JAVA8裏對metaspace能夠在小範圍自動擴展永生代避免溢出。shell
沒有設備、鍵盤或鼠標的模式。
設置字符集
jvm的server工做模式,對應的有client工做模式。使用「java -version」能夠查看當前工做模式
初始Heap大小,使用的最小內存
Java heap最大值,使用的最大內存
經驗: 設置Xms大小等於Xmx大小
表示新生代初始內存的大小,應該小於 -Xms的值
表示新生代可被分配的內存的最大上限,應該小於 -Xmx的值
設定內存的永久保存區域,內存的永久保存區域,VM 存放Class 和 Meta 信息,JVM在運行期間不會清除該區域; 通常狀況下,此參數值使用默認便可,默認大小就夠用了 。程序加載不少class狀況下,超出PermSize狀況下:
JDK1.7會拋出java.lang.OutOfMemoryError: PermGen space異常
JDK1.8下會拋出 ERROR: java.lang.OutOfMemoryError: Metadata space 異常apache
設定最大內存的永久保存區域
經驗: 設置PermSize大小等於MaxPermSize大小
自動將System.gc()調用轉換成一個空操做,即應用中調用System.gc()會變成一個空操做,避免程序員在代碼裏進行System.gc()這種危險操做。System.gc() 除非是到了萬不得也的狀況下使用,都交給JVM吧
年輕代中Eden區與Survivor區的大小比值
保留代碼佔用的內存容量,無大的影響
單個線程堆棧大小值,減小這個值能夠生成更多線程,操做系統對於一個進程內的線程數是有限制的,經驗值在3000-5000左右
CMS 垃圾回收算法,對響應時間的重要性需求 大於 對吞吐量的要求,可以承受垃圾回收線程和應用線程共享處理器資源,而且應用中存在比較多的長生命週期的對象的應用
在使用concurrent gc 的狀況下, 防止 memoryfragmention, 對live object 進行整理, 使 memory 碎片減小。
在FULL GC的時候, 對年老代的壓縮。CMS是不會移動內存的, 所以這個很是容易產生碎片, 致使內存不夠用, 所以, 內存的壓縮這個時候就會被啓用。 增長這個參數是個好習慣。可能會影響性能,可是能夠消除碎片。
使用cms做爲垃圾回收, 使用60%後開始CMS收集
用來限制使用內存,若是不作控制,可能會報出
java.lang.OutOfMemoryError: GC overhead limit exceeded
使用CMS內存收集
設置年輕代爲並行收集
JVM會在遇到OutOfMemoryError時拍攝一個「堆轉儲快照」,並將其保存在一個文件中。
gc的日誌,若是該日誌中出現頻繁的Full GC就是有相關的系統問題,若是不多,說明暫時還算正常
輸出GC的時間戳(以基準時間的形式)
輸出GC的日誌格式
設置DNS緩存時間
鏈接創建超時時間
內容獲取超時設置
是否生成縮略圖的一個框架的配置
export JAVA_OPTS="-server -showversion -Xms2000m -Xmx2000m -Xmn500m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:SurvivorRatio=2 -XX:ReservedCodeCacheSize=256m -Xss1024k -Djava.awt.headless=true -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=60 -XX:+UseGCOverheadLimit -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tomcat_path/logs/dump_tomcat.hprof -Xloggc:/tomcat_path/logs/gc_tomcat.log -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintGCDetails -Dnetworkaddress.cache.ttl=60 -Dsun.net.inetaddr.ttl=60 -DautoStartup=false -Dsun.net.client.defaultConnectTimeout=60000 -Dsun.net.client.defaultReadTimeout=60000 -Djmagick.systemclassloader=no -Djava.security.egd=file:/dev/./urandom -Dfile.encoding=UTF-8"
java.lang.OutOfMemoryError: Java heap space —-JVM Heap(堆)溢出:segmentfault
JVM 在啓動的時候會自動設置 JVM Heap 的值,其初始空間(即-Xms)是物理內存的1/64,最大空間(-Xmx)不可超過物理內存。能夠利用 JVM提供的 -Xmn -Xms -Xmx 等選項可進行設置。Heap 的大小是 Young Generation 和 Tenured Generaion 之和。在 JVM 中若是 98% 的時間是用於 GC,且可用的 Heap size 不足 2% 的時候將拋出此異常信息。緩存
解決方法:tomcat
- 首先檢查代碼,是否存在建立了大量無用對象,且其被引用着,沒法被GC回收 的代碼;
- 手動設置 JVM Heap(堆)的大小;
java.lang.OutOfMemoryError: PermGen space —- PermGen space溢出:
jdk1.8 拋出 ERROR: java.lang.OutOfMemoryError: Metadata space 異常
PermGen space 的全稱是 Permanent Generation space,是指內存的永久保存區域。爲何會內存溢出,這是因爲這塊內存主要是被 JVM 存放Class 和 Meta 信息的,Class 在被 Load 的時候被放入 PermGen space 區域,它和存放 Instance 的 Heap 區域不一樣,sun 的 GC 不會在主程序運行期對 PermGen space 進行清理,因此若是你的 APP 會載入不少 CLASS 的話,就極可能出現 PermGen space 溢出。解決方法: 手動設置 MaxPermSize 大小;
棧溢出了,JVM 依然是採用棧式的虛擬機。函數的調用過程都體如今堆棧和退棧上了。調用構造函數的 「層」太多了,以至於把棧區溢出了。一般來說,通常棧區遠遠小於堆區的,由於函數調用過程每每不會多於上千層,而即使每一個函數調用須要 1K 的空間(這個大約至關於在一個 C 函數內聲明瞭 256 個 int 類型的變量),那麼棧區也不過是須要 1MB 的空間。一般棧的大小是 1-2MB 的。解決方法: 代碼中遞歸也不要遞歸的層次過多;
一切看文章不點贊都是「耍流氓」,嘿嘿ヾ(◍°∇°◍)ノ゙!開個玩笑,動一動你的小手,點贊就完事了,你每一個人出一份力量(點贊 + 評論)就會讓更多的學習者加入進來!很是感謝! ̄ω ̄=