Tomcat、ActiveMQ內存調優

Tomcat內存調優

java.lang.OutOfMemoryError: PermGen space

PermGen space的全稱是Permanent Generation space,是指內存的永久保存區域OutOfMemoryError: PermGen space。從文字上看就是內存溢出,解決方法是加大內存。爲什麼會內存溢出,這是由於這塊內存主要是被JVM存放Class和Meta信息的,Class在被Load的時候被放入PermGen space區域,它和存放Instance的Heap區域不同,GC(Garbage Collection)不會在主程序運行期對PermGen space進行清理,所以如果你的APP會LOAD很多CLASS的話,就很可能出現PermGen space錯誤。這種錯誤常見在web服務器對JSP進行pre compile的時候。如果你的WEB APP下都用了大量的第三方jar, 其大小超過了jvm默認的大小(4M)那麼就會產生此錯誤信息了。
解決方法: 手動設置MaxPermSize大小

a.如果tomcat是以bat方式啓動的,則如下設置:

修改TOMCAT_HOME/bin/catalina.sh
在echo “Using CATALINA_BASE: $CATALINA_BASE”上面加入以下行:
JAVA_OPTS=”-server -XX:PermSize=64M -XX:MaxPermSize=128m”

b.如果tomcat是註冊成了windows服務,以services方式啓動的,則需要修改註冊表中的相應鍵值。

打開註冊表,找到目錄HKEY_LOCAL_MACHINE\SOFTWARE\Apache Software Foundation\Procrun 2.0\htfty\Parameters\Java,其中目錄地址中紅色標註的(如htfty)需要根據不同情況作修改,爲tomcat服務註冊成windows服務的名稱。 可以看到JvmMs和JvmMx項,其中JvmMs設置最小的內存使用參數,JvmMx設置最大的內存使用參數。設置好JvmMs和JvmMx項的值,重啓tomcat服務器即可生效。
建議:將相同的第三方jar文件移置到tomcat/shared/lib目錄下,這樣可以達到減少jar 文檔重複佔用內存的目的。

java.lang.OutOfMemoryError: Java heap space

JVM堆的設置是指java程序運行過程中JVM可以調配使用的內存空間的設置。JVM在啓動的時候會自動設置Heap size的值,其初始空間(即-Xms)是物理內存的1/64,最大空間(-Xmx)是物理內存的1/4。可以利用JVM提供的-Xmn -Xms -Xmx等選項可進行設置。Heap size 的大小是Young Generation 和Tenured Generaion 之和。在JVM中如果98%的時間是用於GC且可用的Heap size 不足2%的時候將拋出此異常信息。
解決方法:手動設置Heap size

a.如果tomcat是以bat方式啓動的,則如下設置:

修改TOMCAT_HOME/bin/catalina.sh
在“echo “Using CATALINA_BASE: $CATALINA_BASE””上面加入以下行:
JAVA_OPTS=”-server -Xms800m -Xmx800m -XX:MaxNewSize=256m”

b.如果tomcat是註冊成了windows服務,以services方式啓動的,則需要修改註冊表中的相應鍵值。

打開註冊表,找到目錄HKEY_LOCAL_MACHINE\SOFTWARE\Apache Software Foundation\Procrun 2.0\htfty\Parameters\Java,其中目錄地址中紅色標註的(如htfty)需要根據不同情況作修改,爲tomcat服務註冊成windows服務的名稱。 可以看到JvmMs和JvmMx項,其中JvmMs設置最小的內存使用參數,JvmMx設置最大的內存使用參數。設置好JvmMs和JvmMx項的值,重啓tomcat服務器即可生效。
提示:Heap Size 最大不要超過可用物理內存的80%,一般的要將-Xms和-Xmx選項設置爲相同,而-Xmn爲1/4的-Xmx值。

ActiveMQ內存配置

ActiveMQ的內核是Java編寫的,也就是說如果服務端沒有Java運行環境ActiveMQ是無法運行的。ActiveMQ啓動時,啓動腳本使用wrapper包裝器來啓動JVM。JVM相關的配置信息在啓動目錄的“wrapper.conf”配置文件中。各位讀者可以通過改變其中的配置項,設置JVM的初始內存大小和最大內存大小(當然還可以進行其他和JVM有關的設置,例如開啓debug模式),如下:
…..
wrapper.java.initmemory=300
wrapper.java.maxmemory=2048
……

以上配置項設置JVM的初始內存大小爲100MB,設置JVM的最大內存大小爲512MB。如果您在更改後使用console參數啓動ActiveMQ,那麼會看到當前ActiveMQ的JVM設置發生了變化:
明確了ActiveMQ的內存區域來源,纔好理解後續的設置內容。ActiveMQ每一個服務節點都是一個獨立的進程。在ActiveMQ主配置文件中,讀者可以找到一個“systemUsage”標記,類似定義如下:
<systemUsage>
<systemUsage>
<memoryUsage>
<memoryUsage percentOfJvmHeap="70" />
</memoryUsage>
<storeUsage>
<storeUsage limit="100 gb"/>
</storeUsage>
<tempUsage>
<tempUsage limit="50 gb"/>
</tempUsage>
</systemUsage>
</systemUsage>

systemUsage:該標記用於設置整個ActiveMQ節點在進程級別的各種“容量”的設置情況。其中可設置的屬性包括:sendFailIfNoSpaceAfterTimeout,當ActiveMQ收到一條消息時,如果ActiveMQ這時已經沒有多餘“容量”了,那麼就會等待一段時間(這裏設置的毫秒數),如果超過這個等待時間ActiveMQ仍然沒有可用的容量,那麼就拒絕接收這條消息並在消息的發送端拋出javax.jms.ResourceAllocationException異常;sendFailIfNoSpace,當ActiveMQ收到一條消息時,如果ActiveMQ這時已經沒有多餘“容量”了,就直接拒絕這條消息(不用等待一段時間),並在消息的發送端拋出javax.jms.ResourceAllocationException異常。
memoryUsage:該子標記設置整個ActiveMQ節點的“可用內存限制”。這個值不能超過上文中您設置的JVM maxmemory的值。其中的percentOfJvmHeap屬性表示使用“百分數值”進行設置,除了這個屬性以外,您還可以使用limit屬性進行固定容量授權,例如:limit=”1000 mb”。這些內存容量將供所有隊列使用。
storeUsage:該標記設置整個ActiveMQ節點,用於存儲“持久化消息”的“可用磁盤空間”。該子標記的limit屬性必須要進行設置。在使用後續介紹的KahaDB方案或者LevelDB方案進行PERSISTENT Message持久化存儲時,這個storeUsage屬性都會起作用;但是如果使用數據庫存儲方案,這個屬性就不會起作用了。
tempUsage:在ActiveMQ 5.X+ 版本中,一旦ActiveMQ服務節點存儲的消息達到了memoryUsage的限制,NON_PERSISTENT Message就會被轉儲到 temp store區域。雖然我們說過NON_PERSISTENT Message不進行持久化存儲,但是ActiveMQ爲了防止“數據洪峯”出現時NON_PERSISTENT Message大量堆積致使內存耗盡的情況出現,還是會將NON_PERSISTENT Message寫入到磁盤的臨時區域——temp store。這個子標記就是爲了設置這個temp store區域的“可用磁盤空間限制”。最後提醒各位讀者storeUsage和tempUsage並不是“最大可用空間”,而是一個閥值。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章