Tomcat內存溢出的三種情況 及解決措施分析

Tomcat內存溢出的原因 在生產環境中tomcat內存設置不好很容易出現內存溢出。造成內存原因是不一樣的,當然處理 法子 也不一樣。 這裏根據 平時遇到的情況 和相干材料進行一個總結。常見的一般會有下面三種情況 : 1.OutOfMemoryError: heap space 2.OutOfMemoryError: PermGen space 3.OutOfMemoryError: unable to create new native thread. Tomcat內存溢出解決方案 對於前兩種情況 ,在利用本身沒有內存透露的情況 下可以用設置tomcat jvm參數來解決。(-Xms -Xmx -XX:PermSize -XX:MaxPermSize) 最後一種可能需要 調劑操作系統 和tomcat jvm參數同時調劑才幹達到 目標。 第一種:是堆溢出。 在JVM中如果98%的光陰是用於GC且可用的 Heap size 不足2%的時候將拋出此異常信息。 沒有內存透露的情況 下,調劑 -Xms -Xmx參數可以解決。 -Xms:初始堆大小 -Xmx:最大堆大小 但堆的大小受下面三方面影響: 1.相干操作系統 的數據模型(32-bt還是64-bit)限制;(32位系統 下,一般限制在1.5G~2G;我在2003 server 系統 下(物理內存:4G和6G,jdk:1.6) 1612M,64爲操作系統 對內存無窮制。) 2.系統 的可用虛擬內存限制; 3.系統 的可用物理內存限制。 堆的大小可以應用 java -Xmx***M version 命令來。支撐的話會出現jdk的版本號,不支撐會報錯。 -Xms -Xmx一般配置成一樣對比好比如set JAVA_OPTS= -Xms1024m -Xmx1024m 第二種:永久保存 區域溢出 PermGen space的全稱是Permanent Generation space,是指內存的永久保存 區域。這一部分用於寄放 Class和Meta的信息,Class在被 Load的時候被放入PermGen space區域,它和和寄放 Instance的Heap區域不同,GC(Garbage Collection)不會在主程序運行期對PermGen space進行清算,所以如果你的APP會LOAD很多CLASS的話,就很可能出現PermGen space差錯。這種差錯常見在web對JSP進行pre compile的時候。但目前的hibernate和spring項目中也很容易出現這樣的問題。?page=1 的帖子有討論的這個問題。可能是由於這些框架會動態class,而且jvm的gc是不會清算 PemGen space的,導致內存溢出。 這一個一般是加大-XX:PermSize -XX:MaxPermSize 來解決問題。 -XX:PermSize 永久保存 區域初始大小 -XX:PermSize 永久保存 區域初始最大值 這一般聯合第一條應用,比如 set JAVA_OPTS= -Xms1024m -Xmx1024m -XX:PermSize=128M -XX:PermSize=256M 有一點需要 注意:java -Xmx***M version 命令來測試的最大堆內存是 -Xmx與 -XX:PermSize的 和 比如系統 支撐最大的jvm堆大小事1.5G,那 -Xmx1024m -XX:PermSize=768M 是無法運行的。 第三種:無法創立新的線程。 這種現象對比少見,也對比奇怪 ,首要是和jvm與系統 內存的比例有關。 這種怪事是因爲JVM已經被系統 分配了大宗的內存(比如1.5G),並且它至少要佔用可用內存的一半。有人創造,在線程個數很多的情況 下,你分配給JVM的內存越多,那麼,上述差錯產生的可能性就越大。 產生 這種現象的原因如下(從這個blog中領會 到原因:): 每一個32位的歷程最多可以應用 2G的可用內存,因爲另外2G被操作系統 保存。這裏假設應用 1.5G給JVM,那麼還餘下500M可用內存。這500M內存中的一部分必須 用於系統 dll的加載,那麼真正剩下的也許只有400M,現在要害的處所出現了:當你應用創立一個線程,在JVM的內存裏也會創立一個Thread對象,但是同時也會在操作系統 裏創立一個真正的物理線程(參考JVM規範),操作系統 會在餘下的400兆內存裏創立這個物理線程,而不是在JVM的1500M的內存堆裏創立。在jdk1.4裏頭,默認的棧大小是256KB,但是在jdk1.5裏頭,默認的棧大小爲1M每線程,因此,在餘下400M的可用內存裏邊我們最多也只能創立 400個可用線程。 這樣結論就出來了,要想創立更多的線程,你必須 減少分配給JVM的最大內存。還有一種做法是讓JVM宿主在你的JNI代碼裏邊。 給出一個有關能夠創立線程的最大個數的估算公式: (MaxProcessMemory - JVMMemory - ReservedOsMemory) / (ThreadStackSize) = Number of threads 對於jdk1.5而言,假設操作系統 保存 120M內存: 1.5GB JVM: (2GB-1.5Gb-120MB)/(1MB) = ~380 threads 1.0GB JVM: (2GB-1.0Gb-120MB)/(1MB) = ~880 threads 在2000/XP/2003的boot.ini裏頭有一個啓動選項,好像是:/PAE /3G ,可以讓用戶歷程最大內存擴充至3G,這時操作系統 只能佔用最多1G的虛存。那樣該當可以讓JVM創立更多的線程。 因此這種情況 需要 聯合操作系統 進行相干調劑。 因此:我們需要 聯合不同情況 對tomcat內存分配進行不同的診斷才幹從根本 上解決問題。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章