Tomcat7 調優及 JVM 參數優化

 

 

Tomcat 的缺省配置是不能穩定長期運行的,也就是不適合生產環境,它會死機,讓你不斷從新啓動,甚至在午夜時分喚醒你。對於操做系統優化來講,是儘量的增大可以使用的內存容量、提升CPU 的頻率,保證文件系統的讀寫速率等。通過壓力測試驗證,在併發鏈接不少的狀況下,CPU 的處理能力越強,系統運行速度越快。javascript

Tomcat 的優化不像其它軟件那樣,簡簡單單的修改幾個參數就能夠了,它的優化主要有三方面,分爲系統優化,Tomcat 自己的優化,Java 虛擬機(JVM)調優。系統優化就不在介紹了,接下來就詳細的介紹一下 Tomcat 自己與 JVM 優化,以 Tomcat 7 爲例。php

1、Tomcat 自己優化css

Tomcat 的自身參數的優化,這塊很像 ApacheHttp Server。修改一下 xml 配置文件中的參數,調整最大鏈接數,超時等。此外,咱們安裝 Tomcat 是,優化就已經開始了。html

一、工做方式選擇java

爲了提高性能,首先就要對代碼進行動靜分離,讓 Tomcat 只負責 jsp 文件的解析工做。如採用 Apache 和 Tomcat 的整合方式,他們之間的鏈接方案有三種選擇,JK、http_proxy 和 ajp_proxy。相對於 JK 的鏈接方式,後兩種在配置上比較簡單的,靈活性方面也一點都不遜色。但就穩定性而言不像JK 這樣久經考驗,因此建議採用 JK 的鏈接方式。 linux

二、Connector 鏈接器的配置web

以前文件介紹過的 Tomcat 鏈接器的三種方式: bio、nio 和 apr,三種方式性能差異很大,apr 的性能最優, bio 的性能最差。而 Tomcat 7 使用的 Connector  默認就啓用的 Apr 協議,但須要系統安裝 Apr 庫,不然就會使用 bio 方式。apache

三、配置文件優化瀏覽器

配置文件優化其實就是對 server.xml 優化,能夠提大大提升 Tomcat 的處理請求的能力,下面咱們來看 Tomcat 容器內的優化。tomcat

默認配置下,Tomcat 會爲每一個鏈接器建立一個綁定的線程池(最大線程數 200),服務啓動時,默認建立了 5 個空閒線程隨時等待用戶請求。

首先,打開 ${TOMCAT_HOME}/conf/server.xml,搜索【<Executor name="tomcatThreadPool"】,開啓並調整爲

1
2
     < Executor  name = "tomcatThreadPool"  namePrefix = "catalina-exec-"
         maxThreads = "500"  minSpareThreads = "20"  maxSpareThreads = "50"  maxIdleTime = "60000" />

注意, Tomcat 7 在開啓線程池前,必定要安裝好 Apr 庫,並能夠啓用,不然會有錯誤報出,shutdown.sh 腳本沒法關閉進程。

而後,修改<Connector …>節點,增長 executor 屬性,搜索【port="8080"】,調整爲

1
2
3
4
5
6
7
8
9
10
11
12
13
14
     < Connector  executor = "tomcatThreadPool"
                port = "8080"  protocol = "HTTP/1.1"
                URIEncoding = "UTF-8"
                connectionTimeout = "30000"
                enableLookups = "false"
                disableUploadTimeout = "false"
                connectionUploadTimeout = "150000"
                acceptCount = "300"
                keepAliveTimeout = "120000"
                maxKeepAliveRequests = "1"
                compression = "on"
                compressionMinSize = "2048"
                compressableMimeType = "text/html,text/xml,text/javascript,text/css,text/plain,image/gif,image/jpg,image/png" 
                redirectPort = "8443"  />

maxThreads :Tomcat 使用線程來處理接收的每一個請求,這個值表示 Tomcat 可建立的最大的線程數,默認值是 200

minSpareThreads:最小空閒線程數,Tomcat 啓動時的初始化的線程數,表示即便沒有人使用也開這麼多空線程等待,默認值是 10。

maxSpareThreads:最大備用線程數,一旦建立的線程超過這個值,Tomcat 就會關閉再也不須要的 socket 線程。

上邊配置的參數,最大線程 500(通常服務器足以),要根據本身的實際狀況合理設置,設置越大會耗費內存和 CPU,由於 CPU 疲於線程上下文切換,沒有精力提供請求服務了,最小空閒線程數 20,線程最大空閒時間 60 秒,固然容許的最大線程鏈接數還受制於操做系統的內核參數設置,設置多大要根據本身的需求與環境。固然線程能夠配置在「tomcatThreadPool」中,也能夠直接配置在「Connector」中,但不能夠重複配置。

URIEncoding:指定 Tomcat 容器的 URL 編碼格式,語言編碼格式這塊倒不如其它 WEB 服務器軟件配置方便,須要分別指定。

connnectionTimeout: 網絡鏈接超時,單位:毫秒,設置爲 0 表示永不超時,這樣設置有隱患的。一般可設置爲 30000 毫秒,可根據檢測實際狀況,適當修改。

enableLookups: 是否反查域名,以返回遠程主機的主機名,取值爲:true 或 false,若是設置爲false,則直接返回IP地址,爲了提升處理能力,應設置爲 false。

disableUploadTimeout:上傳時是否使用超時機制。

connectionUploadTimeout:上傳超時時間,畢竟文件上傳可能須要消耗更多的時間,這個根據你本身的業務須要本身調,以使Servlet有較長的時間來完成它的執行,須要與上一個參數一塊兒配合使用纔會生效。

acceptCount:指定當全部可使用的處理請求的線程數都被使用時,可傳入鏈接請求的最大隊列長度,超過這個數的請求將不予處理,默認爲100個。

keepAliveTimeout:長鏈接最大保持時間(毫秒),表示在下次請求過來以前,Tomcat 保持該鏈接多久,默認是使用 connectionTimeout 時間,-1 爲不限制超時。

maxKeepAliveRequests:表示在服務器關閉以前,該鏈接最大支持的請求數。超過該請求數的鏈接也將被關閉,1表示禁用,-1表示不限制個數,默認100個,通常設置在100~200之間。

compression:是否對響應的數據進行 GZIP 壓縮,off:表示禁止壓縮;on:表示容許壓縮(文本將被壓縮)、force:表示全部狀況下都進行壓縮,默認值爲off,壓縮數據後能夠有效的減小頁面的大小,通常能夠減少1/3左右,節省帶寬。

compressionMinSize:表示壓縮響應的最小值,只有當響應報文大小大於這個值的時候纔會對報文進行壓縮,若是開啓了壓縮功能,默認值就是2048。

compressableMimeType:壓縮類型,指定對哪些類型的文件進行數據壓縮。

noCompressionUserAgents="gozilla, traviata": 對於如下的瀏覽器,不啓用壓縮。

若是已經對代碼進行了動靜分離,靜態頁面和圖片等數據就不須要 Tomcat 處理了,那麼也就不須要配置在 Tomcat 中配置壓縮了。

以上是一些經常使用的配置參數屬性,固然還有好多其它的參數設置,還能夠繼續深刻的優化,HTTP Connector 與 AJP Connector 的參數屬性值,能夠參考官方文檔的詳細說明:

https://tomcat.apache.org/tomcat-7.0-doc/config/http.html

https://tomcat.apache.org/tomcat-7.0-doc/config/ajp.html

2、JVM 優化

 Tomcat 啓動命令行中的優化參數,就是 JVM 的優化 。Tomcat 首先跑在 JVM 之上的,由於它的啓動其實也只是一個 java 命令行,首先咱們須要對這個 JAVA 的啓動命令行進行調優。無論是 YGC 仍是 Full GC,GC 過程當中都會對致使程序運行中中斷,正確的選擇不一樣的 GC 策略,調整 JVM、GC 的參數,能夠極大的減小因爲 GC 工做,而致使的程序運行中斷方面的問題,進而適當的提升 Java 程序的工做效率。可是調整 GC 是以個極爲複雜的過程,因爲各個程序具有不一樣的特色,如:web 和 GUI 程序就有很大區別(Web能夠適當的停頓,但GUI停頓是客戶沒法接受的),並且因爲跑在各個機器上的配置不一樣(主要 cup 個數,內存不一樣),因此使用的 GC 種類也會不一樣。

一、JVM 參數配置方法

Tomcat 的啓動參數位於安裝目錄 ${JAVA_HOME}/bin目錄下,Linux 操做系統就是 catalina.sh 文件。JAVA_OPTS,就是用來設置 JVM 相關運行參數的變量,還能夠在 CATALINA_OPTS 變量中設置。關於這 2 個變量,仍是多少有些區別的:

JAVA_OPTS:用於當 Java 運行時選項「start」、「stop」或「run」命令執行。

CATALINA_OPTS:用於當 Java 運行時選項「start」或「run」命令執行。

爲何有兩個不一樣的變量?它們之間都有什麼區別呢?

首先,在啓動 Tomcat 時,任何指定變量的傳遞方式都是相同的,能夠傳遞到執行「start」或「run」命令中,但只有設定在 JAVA_OPTS 變量裏的參數被傳遞到「stop」命令中。對於 Tomcat 運行過程,可能沒什麼區別,影響的是結束程序,而不是啓動程序。

第二個區別是更微妙,其餘應用程序也可使用 JAVA_OPTS 變量,但只有在 Tomcat 中使用 CATALINA_OPTS 變量。若是你設置環境變量爲只使用 Tomcat,最好你會建議使用 CATALINA_OPTS 變量,而若是你設置環境變量使用其它的 Java 應用程序,例如 JBoss,你應該把你的設置放在JAVA_OPTS 變量中。

二、JVM 參數屬性

32 位系統下 JVM 對內存的限制:不能突破 2GB ,那麼這時你的 Tomcat 要優化,就要講究點技巧了,而在 64 位操做系統上不管是系統內存仍是 JVM 都沒有受到 2GB 這樣的限制。

針對於 JMX 遠程監控也是在這裏設置,如下爲 64 位系統環境下的配置,內存加入的參數以下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
CATALINA_OPTS="
-server 
-Xms6000M 
-Xmx6000M 
-Xss512k 
-XX:NewSize=2250M 
-XX:MaxNewSize=2250M 
-XX:PermSize=128M
-XX:MaxPermSize=256M  
-XX:+AggressiveOpts 
-XX:+UseBiasedLocking 
-XX:+DisableExplicitGC 
-XX:+UseParNewGC 
-XX:+UseConcMarkSweepGC 
-XX:MaxTenuringThreshold=31 
-XX:+CMSParallelRemarkEnabled 
-XX:+UseCMSCompactAtFullCollection 
-XX:LargePageSizeInBytes=128m 
-XX:+UseFastAccessorMethods 
-XX:+UseCMSInitiatingOccupancyOnly
-Duser.timezone=Asia /Shanghai 
-Djava.awt.headless= true "

爲了看着方便,將每一個參數單獨寫一行。上面參數好多啊,可能有人寫到如今都沒見過一個在 Tomcat 的啓動命令里加了這麼多參數,固然,這些參數只是我機器上的,不必定適合你,尤爲是參數後的 value(值)是須要根據你本身的實際狀況來設置的。

上述這樣的配置,基本上能夠達到:

系統響應時間增快;

JVM回收速度增快同時又不影響系統的響應率;

JVM內存最大化利用;

線程阻塞狀況最小化。

JVM 經常使用參數詳解:

-server:必定要做爲第一個參數,在多個 CPU 時性能佳,還有一種叫 -client 的模式,特色是啓動速度比較快,但運行時性能和內存管理效率不高,一般用於客戶端應用程序或開發調試,在 32 位環境下直接運行 Java 程序默認啓用該模式。Server 模式的特色是啓動速度比較慢,但運行時性能和內存管理效率很高,適用於生產環境,在具備 64 位能力的 JDK 環境下默認啓用該模式,能夠不配置該參數。

-Xms:表示 Java 初始化堆的大小,-Xms 與-Xmx 設成同樣的值,避免 JVM 反覆從新申請內存,致使性能大起大落,默認值爲物理內存的 1/64,默認(MinHeapFreeRatio參數能夠調整)空餘堆內存小於 40% 時,JVM 就會增大堆直到 -Xmx 的最大限制。

-Xmx:表示最大 Java 堆大小,當應用程序須要的內存超出堆的最大值時虛擬機就會提示內存溢出,而且致使應用服務崩潰,所以通常建議堆的最大值設置爲可用內存的最大值的80%。如何知道個人 JVM 可以使用最大值,使用 java -Xmx512M -version 命令來進行測試,而後逐漸的增大 512 的值,若是執行正常就表示指定的內存大小可用,不然會打印錯誤信息,默認值爲物理內存的 1/4,默認(MinHeapFreeRatio參數能夠調整)空餘堆內存大於 70% 時,JVM 會減小堆直到-Xms 的最小限制。

-Xss:表示每一個 Java 線程堆棧大小,JDK 5.0 之後每一個線程堆棧大小爲 1M,之前每一個線程堆棧大小爲 256K。根據應用的線程所需內存大小進行調整,在相同物理內存下,減少這個值能生成更多的線程,可是操做系統對一個進程內的線程數仍是有限制的,不能無限生成,經驗值在 3000~5000 左右。通常小的應用, 若是棧不是很深, 應該是128k 夠用的,大的應用建議使用 256k 或 512K,通常不易設置超過 1M,要否則容易出現out ofmemory。這個選項對性能影響比較大,須要嚴格的測試。

-XX:NewSize:設置新生代內存大小。

-XX:MaxNewSize:設置最大新生代新生代內存大小

-XX:PermSize:設置持久代內存大小

-XX:MaxPermSize:設置最大值持久代內存大小,永久代不屬於堆內存,堆內存只包含新生代和老年代。

-XX:+AggressiveOpts:做用如其名(aggressive),啓用這個參數,則每當 JDK 版本升級時,你的 JVM 都會使用最新加入的優化技術(若是有的話)。

-XX:+UseBiasedLocking:啓用一個優化了的線程鎖,咱們知道在咱們的appserver,每一個http請求就是一個線程,有的請求短有的請求長,就會有請求排隊的現象,甚至還會出現線程阻塞,這個優化了的線程鎖使得你的appserver內對線程處理自動進行最優調配。

-XX:+DisableExplicitGC:在 程序代碼中不容許有顯示的調用「System.gc()」。每次在到操做結束時手動調用 System.gc() 一下,付出的代價就是系統響應時間嚴重下降,就和關於 Xms,Xmx 裏的解釋的原理同樣,這樣去調用 GC 致使系統的 JVM 大起大落。

-XX:+UseConcMarkSweepGC:設置年老代爲併發收集,即 CMS gc,這一特性只有 jdk1.5
後續版本才具備的功能,它使用的是 gc 估算觸發和 heap 佔用觸發。咱們知道頻頻繁的 GC 會造面 JVM
的大起大落從而影響到系統的效率,所以使用了 CMS GC 後能夠在 GC 次數增多的狀況下,每次 GC 的響應時間卻很短,好比說使用了 CMS
GC 後通過 jprofiler 的觀察,GC 被觸發次數很是多,而每次 GC 耗時僅爲幾毫秒。

-XX:+UseParNewGC:對新生代採用多線程並行回收,這樣收得快,注意最新的 JVM 版本,當使用 -XX:+UseConcMarkSweepGC 時,-XX:UseParNewGC 會自動開啓。所以,若是年輕代的並行 GC 不想開啓,能夠經過設置 -XX:-UseParNewGC 來關掉。

-XX:MaxTenuringThreshold:設置垃圾最大年齡。若是設置爲0的話,則新生代對象不通過 Survivor 區,直接進入老年代。對於老年代比較多的應用(須要大量常駐內存的應用),能夠提升效率。若是將此值設置爲一 個較大值,則新生代對象會在 Survivor 區進行屢次複製,這樣能夠增長對象在新生代的存活時間,增長在新生代即被回收的機率,減小Full GC的頻率,這樣作能夠在某種程度上提升服務穩定性。該參數只有在串行 GC 時纔有效,這個值的設置是根據本地的 jprofiler 監控後獲得的一個理想的值,不能一律而論原搬照抄。

-XX:+CMSParallelRemarkEnabled:在使用 UseParNewGC 的狀況下,儘可能減小 mark 的時間。

-XX:+UseCMSCompactAtFullCollection:在使用 concurrent gc 的狀況下,防止 memoryfragmention,對 live object 進行整理,使 memory 碎片減小。

-XX:LargePageSizeInBytes:指定 Java heap 的分頁頁面大小,內存頁的大小不可設置過大, 會影響 Perm 的大小。

-XX:+UseFastAccessorMethods:使用 get,set 方法轉成本地代碼,原始類型的快速優化。

-XX:+UseCMSInitiatingOccupancyOnly:只有在 oldgeneration 在使用了初始化的比例後 concurrent collector 啓動收集。

-Duser.timezone=Asia/Shanghai:設置用戶所在時區。

-Djava.awt.headless=true:這個參數通常咱們都是放在最後使用的,這全參數的做用是這樣的,有時咱們會在咱們的 J2EE 工程中使用一些圖表工具如:jfreechart,用於在 web 網頁輸出 GIF/JPG 等流,在 winodws 環境下,通常咱們的 app server 在輸出圖形時不會碰到什麼問題,可是在linux/unix 環境下常常會碰到一個 exception 致使你在 winodws 開發環境下圖片顯示的好好但是在 linux/unix 下卻顯示不出來,所以加上這個參數以避免避這樣的狀況出現。

-Xmn:新生代的內存空間大小,注意:此處的大小是(eden+ 2 survivor space)。與 jmap -heap 中顯示的 New gen 是不一樣的。整個堆大小 = 新生代大小 + 老生代大小 + 永久代大小。在保證堆大小不變的狀況下,增大新生代後,將會減少老生代大小。此值對系統性能影響較大,Sun官方推薦配置爲整個堆的 3/8。

-XX:CMSInitiatingOccupancyFraction:當堆滿以後,並行收集器便開始進行垃圾收集,例如,當沒有足夠的空間來容納新分配或提高的對象。對於 CMS 收集器,長時間等待是不可取的,由於在併發垃圾收集期間應用持續在運行(而且分配對象)。所以,爲了在應用程序使用完內存以前完成垃圾收集週期,CMS 收集器要比並行收集器更先啓動。由於不一樣的應用會有不一樣對象分配模式,JVM 會收集實際的對象分配(和釋放)的運行時數據,而且分析這些數據,來決定何時啓動一次 CMS 垃圾收集週期。這個參數設置有很大技巧,基本上知足(Xmx-Xmn)*(100-CMSInitiatingOccupancyFraction)/100 >= Xmn 就不會出現 promotion failed。例如在應用中 Xmx 是6000,Xmn 是 512,那麼 Xmx-Xmn 是 5488M,也就是老年代有 5488M,CMSInitiatingOccupancyFraction=90 說明老年代到 90% 滿的時候開始執行對老年代的併發垃圾回收(CMS),這時還 剩 10% 的空間是 5488*10% = 548M,因此即便 Xmn(也就是新生代共512M)裏全部對象都搬到老年代裏,548M 的空間也足夠了,因此只要知足上面的公式,就不會出現垃圾回收時的 promotion failed,所以這個參數的設置必須與 Xmn 關聯在一塊兒。

-XX:+CMSIncrementalMode:該標誌將開啓 CMS 收集器的增量模式。增量模式常常暫停 CMS 過程,以便對應用程序線程做出徹底的讓步。所以,收集器將花更長的時間完成整個收集週期。所以,只有經過測試後發現正常 CMS 週期對應用程序線程干擾太大時,才應該使用增量模式。因爲現代服務器有足夠的處理器來適應併發的垃圾收集,因此這種狀況發生得不多,用於但 CPU狀況。

-XX:NewRatio:年輕代(包括 Eden 和兩個 Survivor 區)與年老代的比值(除去持久代),-XX:NewRatio=4 表示年輕代與年老代所佔比值爲 1:4,年輕代佔整個堆棧的 1/5,Xms=Xmx 而且設置了 Xmn 的狀況下,該參數不須要進行設置。

-XX:SurvivorRatio:Eden 區與 Survivor 區的大小比值,設置爲 8,表示 2 個 Survivor 區(JVM 堆內存年輕代中默認有 2 個大小相等的 Survivor 區)與 1 個 Eden 區的比值爲 2:8,即 1 個 Survivor 區佔整個年輕代大小的 1/10。

-XX:+UseSerialGC:設置串行收集器。

-XX:+UseParallelGC:設置爲並行收集器。此配置僅對年輕代有效。即年輕代使用並行收集,而年老代仍使用串行收集。

-XX:+UseParallelOldGC:配置年老代垃圾收集方式爲並行收集,JDK6.0 開始支持對年老代並行收集。

-XX:ConcGCThreads:早期 JVM 版本也叫-XX:ParallelCMSThreads,定義併發 CMS 過程運行時的線程數。好比 value=4 意味着 CMS 週期的全部階段都以 4 個線程來執行。儘管更多的線程會加快併發 CMS 過程,但其也會帶來額外的同步開銷。所以,對於特定的應用程序,應該經過測試來判斷增長 CMS 線程數是否真的可以帶來性能的提高。若是還標誌未設置,JVM 會根據並行收集器中的 -XX:ParallelGCThreads 參數的值來計算出默認的並行 CMS 線程數。

-XX:ParallelGCThreads:配置並行收集器的線程數,即:同時有多少個線程一塊兒進行垃圾回收,此值建議配置與 CPU 數目相等。

-XX:OldSize:設置 JVM 啓動分配的老年代內存大小,相似於新生代內存的初始大小 -XX:NewSize。

以上就是一些經常使用的配置參數,有些參數是能夠被替代的,配置思路須要考慮的是 Java 提供的垃圾回收機制。虛擬機的堆大小決定了虛擬機花費在收集垃圾上的時間和頻度。收集垃圾可以接受的速度和應用有關,應該經過分析實際的垃圾收集的時間和頻率來調整。假如堆的大小很大,那麼徹底垃圾收集就會很慢,可是頻度會下降。假如您把堆的大小和內存的須要一致,徹底收集就很快,可是會更加頻繁。調整堆大小的的目的是最小化垃圾收集的時間,以在特定的時間內最大化處理客戶的請求。在基準測試的時候,爲確保最好的性能,要把堆的大小設大,確保垃圾收集不在整個基準測試的過程當中出現。

假如系統花費不少的時間收集垃圾,請減少堆大小。一次徹底的垃圾收集應該不超過 3-5 秒。假如垃圾收集成爲瓶頸,那麼須要指定代的大小,檢查垃圾收集的周詳輸出,研究垃圾收集參數對性能的影響。當增長處理器時,記得增長內存,由於分配可以並行進行,而垃圾收集不是並行的。

三、設置系統屬性

以前說過,Tomcat 的語言編碼,配置起來很慢,要通過屢次設置才能夠了,不然中文頗有可能出現亂碼狀況。譬如漢字「中」,以 UTF-8 編碼後獲得的是 3 字節的值 %E4%B8%AD,而後經過 GET 或者 POST 方式把這 3 個字節提交到 Tomcat 容器,若是你不告訴 Tomcat 個人參數是用 UTF-8編碼的,那麼 Tomcat 就認爲你是用 ISO-8859-1 來編碼的,而 ISO8859-1(兼容 URI 中的標準字符集 US-ASCII)是兼容 ASCII 的單字節編碼而且使用了單字節內的全部空間,所以 Tomcat 就覺得你傳遞的用 ISO-8859-1 字符集編碼過的 3 個字符,而後它就用 ISO-8859-1 來解碼。

設置起來不難使用「 -D<名稱>=<值> 」來設置系統屬性:

-Djavax.servlet.request.encoding=UTF-8

-Djavax.servlet.response.encoding=UTF-8 

-Dfile.encoding=UTF-8 

-Duser.country=CN 

-Duser.language=zh

四、常見的 Java 內存溢出有如下三種

(1) java.lang.OutOfMemoryError: Java heap space —-JVM Heap(堆)溢出

JVM 在啓動的時候會自動設置 JVM Heap 的值,其初始空間(即-Xms)是物理內存的1/64,最大空間(-Xmx)不可超過物理內存。能夠利用 JVM提供的 -Xmn -Xms -Xmx 等選項可進行設置。Heap 的大小是 Young Generation 和 Tenured Generaion 之和。在 JVM 中若是 98% 的時間是用於 GC,且可用的 Heap size 不足 2% 的時候將拋出此異常信息。

解決方法:手動設置 JVM Heap(堆)的大小。  
(2) java.lang.OutOfMemoryError: PermGen space  —- PermGen space溢出。

PermGen space 的全稱是 Permanent Generation space,是指內存的永久保存區域。爲何會內存溢出,這是因爲這塊內存主要是被 JVM 存放Class 和 Meta 信息的,Class 在被 Load 的時候被放入 PermGen space 區域,它和存放 Instance 的 Heap 區域不一樣,sun 的 GC 不會在主程序運行期對 PermGen space 進行清理,因此若是你的 APP 會載入不少 CLASS 的話,就極可能出現 PermGen space 溢出。

解決方法: 手動設置 MaxPermSize 大小

(3) java.lang.StackOverflowError   —- 棧溢出

棧溢出了,JVM 依然是採用棧式的虛擬機,這個和 C 與 Pascal 都是同樣的。函數的調用過程都體如今堆棧和退棧上了。調用構造函數的 「層」太多了,以至於把棧區溢出了。一般來說,通常棧區遠遠小於堆區的,由於函數調用過程每每不會多於上千層,而即使每一個函數調用須要 1K 的空間(這個大約至關於在一個 C 函數內聲明瞭 256 個 int 類型的變量),那麼棧區也不過是須要 1MB 的空間。一般棧的大小是 1-2MB 的。
一般遞歸也不要遞歸的層次過多,很容易溢出。

解決方法:修改程序。

更多信息,請參考如下文章:

JVM 垃圾回收調優總結

http://developer.51cto.com/art/201201/312639.htm

JVM調優總結:典型配置舉例

http://developer.51cto.com/art/201201/311739.htm

JVM基礎:JVM參數設置、分析 

http://developer.51cto.com/art/201201/312018.htm

JVM 堆內存相關的啓動參數:年輕代、老年代和永久代的內存分配

http://www.2cto.com/kf/201409/334840.html

Java 虛擬機–新生代與老年代GC

http://my.oschina.net/sunnywu/blog/332870

JVM(Java虛擬機)優化大全和案例實戰

http://blog.csdn.net/kthq/article/details/8618052

JVM內存區域劃分Eden Space、Survivor Space、Tenured Gen,Perm Gen解釋 

http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=29632145&id=4616836

相關文章
相關標籤/搜索