版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、apache 服務器出現(xiàn)內存溢出的解決方法2011-10-0814:26tomcat 內存溢出的原因在生產環(huán)境中 tomcat 內存設置不好很容易出現(xiàn)內存溢出。造成內存溢出是不一樣的,當然處理方式也不一樣。這里根據(jù)平時遇到的情況和相關資料進行一個總結。常見的一般會有下面三種情況:1.outofmemoryerrorjavaheapspace2.outofmemoryerrorpermgenspace3.outofmemoryerrorunabletocreatenewnativethread.tomcat 內存溢出解決方案對于前兩種情況,在應用本身沒有內存泄露的情況下可以用設置 tomcatj
2、vm 參數(shù)來解決。-xms-xmx-xx : permsize-xx : maxpermsize )最后一種可能需要調整操作系統(tǒng)和tomcatjvm 參數(shù)同時調整才能達到目的。第一種:是堆溢出。原因分析:jvm 堆的設置是指java 程序運行過程中 jvm 可以調配使用的內存空間的設置 .jvm 在啟動的時候會自動設置heapsize的值,其初始空間(即-xms)是物理內存的1/64 ,最大空間(-xmx)是物理內存的1/4??梢岳?jvm 提供的 -xmn-xms-xmx 等選項可進行設置。 heapsize 的大小是 younggeneration 和tenuredgeneraion 之
3、和。在 jvm 中如果 98 的時間是用于gc 且可用的 heapsize 不足 2 的時候將拋出此異常信息。heapsize最大不要超過可用物理內存的 80%, 一般的要將-xms和-xmx選項設置為相同,而-xmn為 1/4 的 -xmx 值。沒有內存泄露的情況下,調整-xms-xmx 參數(shù)可以解決。-xms :初始堆大小-xmx :最大堆大小但堆的大小受下面三方面影響:1. 相關操作系統(tǒng)的數(shù)據(jù)模型( 32-bt 還是 64-bit )限制;(32 位系統(tǒng)下,一般限制在 1.5g2g ;我在 2003server 系統(tǒng)下(物理內存: 4g 和 6g , jdk : 1.6 )測試1612m
4、 , 64 位操作系統(tǒng)對內存無限制。)2. 系統(tǒng)的可用虛擬內存限制;3. 系統(tǒng)的可用物理內存限制。堆的大小可以使用 java-xmx*mversion 命令來測試。支持的話會出現(xiàn)jdk 的版本號,不支持會報錯。-xms-xmx 一般配置成一樣比較好比如 setjava_opts=-xms1024m-xmx1024m 其初始空間( 即-xms) 是物理內存的 1/64 ,最大空間 (-xmx) 是物理內存的 1/4 ??梢岳?jvm 提供的 -xmn-xms-xmx 等選項可進行設置實例,以下給出 1g 內存環(huán)境下javajvm 的參數(shù)設置參考:java_opts=-server-xms800
5、m-xmx800m-xx:permsize=64m-xx:maxnewsize =256m-xx:maxpermsize=128m-djava.awt.headless=truejava_opts=-server-xms768m-xmx768m-xx:permsize=128m-xx:maxpermsize=256m-xx:newsize=192m-xx: maxnewsize =384mcatalina_opts=-server-xms768m-xmx768m-xx:permsize=128m-xx:maxpermsize=256m-xx:newsize=192m-xx:maxnewsize
6、 =384m 服務器為 1g 內存:java_opts=-server-xms800m-xmx800m-xx:permsize=64m-xx:maxnewsize =256m-xx:maxpermsize=128m-djava.awt.headless=true服務器為 64 位、 2g 內存:java_opts=-server-xms1024m-xmx1536m-xx:permsize=128m-xx:maxnewsize =256m-xx:maxpermsize=256m 解決方案 1 : 前提:是執(zhí)行startup.bat 啟動 tomcat 的方式linux 服務器:在 /usr/lo
7、cal/apache-tomcat-5.5.23/bin 目錄下的 catalina.sh添加: java_opts=-xms512m-xmx1024m或者java_opts=-server-xms800m-xmx800m-xx:maxnewsize =256m或者catalina_opts=-server-xms256m-xmx300mwindows 服務器:在 catalina.bat 最前面加入setjava_opts=-xms128m-xmx350m或者setcatalina_opts=-xmx300m-xms256m(區(qū)別是一個直接設置 jvm 內存,另一個設置tomcat 內存,
8、catalina_opts 似乎可以與java_opts不加區(qū)別的使用)基本參數(shù)說明-client , -server這兩個參數(shù)用于設置虛擬機使用何種運行模式,一定要作為第一個參數(shù), client 模式啟動比較快,但運行時性能和內存管理效率不如 server 模式,通常用于客戶端應用程序。相反, server 模式啟動比client 慢,但可獲得更高的運行性能。在 windows 上,缺省的虛擬機類型為 client 模式,如果要使用 server 模式,就需要在啟動虛擬機時加-server 參數(shù),以獲得更高性能,對服務器端應用,推薦采用 server 模式,尤其是多個cpu 的系統(tǒng)。在lin
9、ux , solaris 上缺省采用 server 模式。此外,在多 cup 下,建議用 server 模式 -xms設置虛擬機可用內存堆的初始大小, 缺省單位為字節(jié), 該大小為 1024 的整數(shù)倍并且要大于 1mb , 可用 k(k)或m(m)為單位來設置較大的內存數(shù)。初始堆大小為2mb o加“ m”說明是mb ,否則就是kb 了。例如: -xms6400k , -xms256m-xmx設置虛擬機的最大可用大小,缺省單位為字節(jié)。該值必須為 1024 整數(shù)倍,并且要大于2mb ??捎?k(k)或 m(m) 為單位來設置較大的內存數(shù)。缺省堆最大值為 64mb 。例如: -xmx81920k ,
10、-xmx80m當應用程序申請了大內存運行時虛擬機拋出 java.lang.outofmemoryerror:javaheapspace 錯誤, 就需要使用 -xmx 設置較大的可用內存堆。permsize/maxpermsize :定義 perm 段的尺寸,即永久保存區(qū)域的大小, permsize 為 jvm 啟動時初始化 perm 的內存大??; maxpermsize 為最大可占用的 perm 內存大小。在用戶生產環(huán)境上一般將這兩個值設為相同,以減少運行期間系統(tǒng)在內存申請上所花的開銷。如果用 startup.bat 啟動 tomcat,ok 設置生效 .夠成功的分配200m 內存 .解決方案
11、 2 :前提:是執(zhí)行startup.bat 啟動 tomcat 的方式手動設置 heapsizewindows 服務器:修改 tomcat_home/bin/catalina.bat , 在“ echousingcatalina_base:$catalina_base ”上面加入以下行:java 代碼setjava_opts=%java_opts%-server-xms800m-xmx800m-xx:maxnewsize =256m注: java_opts 是保留先前設置。linux 服務器:修改 tomcat_home/bin/catalina.sh在“ echousingcatalina_
12、base:$catalina_base ”上面加入以下行:java_opts=$java_opts-server-xms800m-xmx800m-xx:maxnewsize =256m 注:$java_opts 是保留先前設置。 解決方案 3 : 前提:是執(zhí)行windows 的系統(tǒng)服務啟動tomcat 的方式但是如果不是執(zhí)行startup.bat 啟動 tomcat 而是利用 windows 的系統(tǒng)服務啟動tomcat 服務 ,上面的設置就不生效了 ,就是說 setjava_opts=-xms128m-xmx350m沒起作用.上面分配200m 內存就 oom 了 .windows 服務執(zhí)行的是
13、bintomcat.exe. 他讀取注冊表中的值 ,而不是 catalina.bat 的設置.解決辦法:修改注冊表hkey_local_machinesoftwareapachesoftwarefoundationtomcatservicemanagertomcat5parametersjavaoptions原值為-dcatalina.home=c:apachegrouptomcat5.0-djava.endorsed.dirs=c:apachegrouptomcat5.0commonendorsed-xrs加入 -xms300m-xmx350m重起 tomcat 服務 ,設置生效 解決方案
14、4 : 前提:是執(zhí)行windows 的系統(tǒng)服務啟動tomcat 的方式在安裝 tomcat 時若有勾選 ntservice(nt/2000/xponly)則安裝完成后在安裝目錄的 bin 目錄里會有一個tomcat.exe 的檔案先把 tomcat 的服務停掉在命令列模式下(運行里輸入 cmd )將目錄切換到 tomcat 的 bin 目錄用下面的命令把服務移除tomcat-uninstallapachetomcat4.1接下來,寫個批處理。內容如下setservicename=apachetomcat4.1setcatalina_home=e:tomcat4.1.24setclasspath
15、=d:j2sdk1.4.1_01libsetjavaclasspath=%classpath%setjavaclasspath=%javaclasspath%;? talina_home%binbootstrap.jarsetjavaclasspath=%javaclasspath%;? talina_home%commonlibservlet.jarsetjavaclasspath=%javaclasspath%;%java_home%libtools.jartomcat.exe-install%servicename%java_home%jrebinserverjvm.dll-djava.
16、class.path=%javaclasspath%-dcatalina.home= ? talina_home%-xms512m-xmx768m-startorg.apache.catalina.startup.bootstrap-paramsstart-stoporg.apache.catalina.startup.bootstrap-paramsstop-out ? talina_home%logsstdout.log-err ? talina_home%logsstderr.log注意,從tomcat.exe-install開始的是最后一行!不要手工回車換行把這一行分成了好幾段。保存后
17、在命令行下執(zhí)行這個bat 文件,注意執(zhí)行的時候將“服務”窗口關閉。第二種:永久保存區(qū)域溢出原因分析:permgenspace 的全稱是 permanentgenerationspace, 是指內存的永久保存區(qū)域,這塊內存主要是被jvm 存放 class 和 meta 信息的 ,class 在被 loader 時就會被放到 permgenspace 中,它和存放類實例(instance) 的 heap 區(qū)域不同 ,gc(garbagecollection) 不會在主程序運行期對 permgenspace 進行清理,所以如果你的應用中有很class 的話 ,就很可能出現(xiàn)permgenspace 錯
18、誤,這種錯誤常見在 web 服務器對 jsp 進行 precompile 的時候。 如果你的 webapp 下都用了大量的第三方jar, 其大小超過了 jvm 默認的大小 (4m) 那么就會產生此錯誤信息了。但目前的 hibernate 和 spring 項目中也很容易出現(xiàn)這樣的問題??赡苁怯捎谶@些框架會動態(tài)class ,而且 jvm 的 gc 是不會清理pemgenspace 的,超過了 jvm 默認的大小 (4m) ,導致內存溢出。建議: 將相同的第三方jar 文件移置到 tomcat/shared/lib 目錄下, 這樣可以達到減少jar 文檔重復占用內存的目的。這一個一般是加大-xx
19、: permsize-xx : maxpermsize 來解決問題。-xx : permsize 永久保存區(qū)域初始大小-xx : permsize 永久保存區(qū)域初始最大值這一般結合第一條使用,比如 setjava_opts=-xms1024m-xmx1024m-xx :permsize=128m-xx : permsize=256m有一點需要注意: java-xmx*mversion 命令來測試的最大堆內存是-xmx 與 -xx : permsize 的和比如系統(tǒng)支持最大的 jvm 堆大小事 1.5g ,那 -xmx1024m-xx : permsize=768m 是無法運行的。 解決方案 1
20、 : linux 服務器:在 catalina.sh 的第一行增加:java_opts=-xms64m-xmx256m-xx:permsize=128m-xx: maxnewsize =256m或者在“ echousingcatalina_base:$catalina_base ”上面加入以下行:java_opts=-server-xx:permsize=64m-xx:maxpermsize=128mwindows 服務器:在 catalina.bat 的第一行增加:setjava_opts=-xms64m-xmx256m-xx:permsize=128m-xx:maxnewsize =256
21、m-xx:maxpermsize=256m 解決方案 2 : 修改 tomcat_home/bin/catalina.bat ( linux 下為 catalina.sh ),在 java 代碼“ echousingcatalina_base:$catalina_base ”上面加入以下行:setjava_opts=%java_opts%-server-xx:permsize=128m- xx:maxpermsize=512m “ echousingcatali na_base:$catalina_base ”上面加入以下行:setjava_opts=%java_opts%-server-xx
22、:permsize=128m-xx:maxpermsize=512mcatalina.sh下為:java 代碼java_opts=$java_opts-server-xx:permsize=128m-xx:maxpermsize=512mjava_opts=$java_opts-server-xx:permsize=128m-xx:maxpermsize=512m第三種:無法創(chuàng)建新的線程。這種現(xiàn)象比較少見,也比較奇怪,主要是和jvm 與系統(tǒng)內存的比例有關。這種怪事是因為jvm 已經(jīng)被系統(tǒng)分配了大量的內存(比如 1.5g ),并且它至少要占用可用內存的一半。有人發(fā)現(xiàn),在線程個數(shù)很多的情況下,你分
23、配給jvm 的內存越多,那么,上述錯誤發(fā)生的可能性就越原因分析(從這個blog中了解到原因:/hexiong/blog/item/16dc9e518fb10c2542a75b3c.html):每一個32位的進程最多可以使用 2g的可用內存,因為另外2g被操作系統(tǒng)保留。這里假設使用1.5g 給jvm ,那么還余下500m 可用內存。這500m內存中的一部分必須用于系統(tǒng)dll的加載,那么真正剩下的也許只有400m ,現(xiàn)在關鍵的地方出現(xiàn)了:當你使用java創(chuàng)建一個線程,在 jvm的內存里也會創(chuàng)建一個thread對象,但是同時也會在操作系統(tǒng)里創(chuàng)建一個真正的物理線程(
24、參考 jvm規(guī)范),操作系統(tǒng)會在 余下的400兆內存里創(chuàng)建這個物理線程,而不是在jvm的1500m的內存堆里創(chuàng)建。在jdk1.4里頭,默認的棧大小是256kb ,但是在jdk1.5里頭,默認的棧大小為 1m每線程,因此,在余下 400m的可用內 存里邊我們最多也只能創(chuàng)建400個可用線程。這樣結論就出來了,要想創(chuàng)建更多的線程,你必須減少分配給jvm的最大內存。還有一種做法是讓jvm宿主在你的jni代碼里邊。給出一個有關能夠創(chuàng)建線程的最大個數(shù)的估算公式:(maxprocessmemory-jvmmemory-reservedosmemory) / (threadstacksize )=number
25、ofthreads對于jdk1.5而言,假設操作系統(tǒng)保留120m內存:1.5gbjvm : (2gb-1.5gb-120mb ) / (1mb) =380threads1.0gbjvm : (2gb-1.0gb-120mb ) / (1mb) =880threads在2000/xp/2003 的boot.ini里頭有一個啟動選項,好像是:/pae/3g ,可以讓用戶進程最大內存擴充至3g,這時操作系統(tǒng)只能占用最多1g的虛存。那樣應該可以讓 jvm創(chuàng)建更多的線程。因此這種情況需要結合操作系統(tǒng)進行相關調整。tomcat 內存分配進行不同的診斷才能從根本上解決問題。檢測當前 jvm 內存使用情況:s
26、ystem.out.println(jvmmaxmemory:+runtime.getruntime().maxmemory()/1024/1024+m);system.out.println(jvmisusingmemory:+runtime.getruntime().totalmemory()/1024/1024+m);system.out.println(jvmisfreememory:+runtime.getruntime().freememory()/1024/1024+m); 這三個方法都是說jvm 的內存使用情況而不是操作系統(tǒng)的內存;maxmemory() 這個方法返回的是jav
27、a 虛擬機(這個進程)能構從操作系統(tǒng)那里挖到的最大的內存,以字節(jié)為單位, 如果在運行 java 程序的時候, 沒有添加 -xmx 參數(shù), 那么就是 64 兆, 也就是說 maxmemory()返回的大約是64*1024*1024 字節(jié),這是java 虛擬機默認情況下能從操作系統(tǒng)那里挖到的最大的內存。如果添加了 -xmx 參數(shù), 將以這個參數(shù)后面的值為準, 例如 java-cpclasspath-xmx512mclassname , 那么最大內存就是512*1024*0124 字節(jié)。totalmemory() 這個方法返回的是 java 虛擬機現(xiàn)在已經(jīng)從操作系統(tǒng)那里挖過來的內存大小,也就是jav
28、a 虛擬機這個進程當時所占用的所有內存。如果在運行java 的時候沒有添加-xms 參數(shù),那么,在 java程序運行的過程的, 內存總是慢慢的從操作系統(tǒng)那里挖的, 基本上是用多少挖多少, 直挖到 maxmemory()為止,所以totalmemory() 是慢慢增大的。如果用了 -xms 參數(shù),程序在啟動的時候就會無條件的從操作系統(tǒng)中挖 -xms 后面定義的內存數(shù),然后在這些內存用的差不多的時候,再去挖。freememory() 是什么呢,剛才講到如果在運行 java 的時候沒有添加-xms 參數(shù),那么,在 java 程序運行的過程的,內存總是慢慢的從操作系統(tǒng)那里挖的,基本上是用多少挖多少,但
29、是java 虛擬機100 的情況下是會稍微多挖一點的,這些挖過來而又沒有用上的內存,實際上就是freememory() ,所以freememory() 的值一般情況下都是很小的, 但是如果你在運行java 程序的時候使用了 -xms , 這個時候因為程序在啟動的時候就會無條件的從操作系統(tǒng)中挖-xms 后面定義的內存數(shù),這個時候,挖過來的內存可能大部分沒用上,所以這個時候 freememory() 可能會有些解決方案jvm 堆大小的調整sunhotspot1.4.1 使用分代收集器,它把堆分為三個主要的域:新域、舊域以及永久域。 jvm 生成的所有新對象放在新域中。一旦對象經(jīng)歷了一定數(shù)量的垃圾收
30、集循環(huán)后,便獲得使用期并進入舊域。在永久域中 jvm 則存儲 class 和 method 對象。就配置而言,永久域是一個獨立域并且不認為是堆的一部分。下面介紹如何控制這些域的大小。可使用-xms和-xmx控制整個堆的原始大小或最大值。下面的命令是把初始大小設置為128m :java 曉ms128m%mx256m為控制新域的大小,可使用 -xx:newratio設置新域在堆中所占的比例。下面的命令把整個堆設置成128m ,新域比率設置成3 ,即新域與舊域比例為 1 : 3,新域為堆的 1/4或 32m :java 曉ms128m xmx128m%x:newratio=3可使用-xx:newsi
31、ze 和-xx: maxnewsize設置新域的初始值和最大值。下面的命令把新域的初始值和最大值設置成64m:java 曉ms256m xmx256m %mn64m永久域默認大小為 4m 。運行程序時, jvm 會調整永久域的大小以滿足需要。每次調整時, jvm 會對堆進行一次完全的垃圾收集。使用 -xx:maxpersize 標志來增加永久域搭大小。在weblogicserver 應用程序加載較多類時,經(jīng)常需要增加永久域的最大值。 當 jvm 加載類時, 永久域中的對象急劇增加, 從而使 jvm 不斷調整永久域大小。為了避免調整,可使用 -xx:persize 標志設置初始值。下面把永久域初
32、始值設置成32m ,最大值設置成64mjava-xms512m-xmx512m-xmn128m-xx:permsize=32m-xx:maxpermsize=64m默認狀態(tài)下, hotspot 在新域中使用復制收集器。該域一般分為三個部分。第一部分為 eden ,用于生成新的對象。另兩部分稱為救助空間,當 eden 充滿時,收集器停止應用程序,把所有可到達對象復制到當前的 from 救助空間,一旦當前的 from 救助空間充滿,收集器則把可到達對象復制到當前的 to 救助空間。 from 和 to 救助空間互換角色。維持活動的對象將在救助空間不斷復制,直到它們獲得使用期并轉入舊域。使用 -xx
33、:survivorratio 可控制新域子空間的大小。同 newration 一樣, survivorration 規(guī)定某救助域與 eden 空間的比值。比如,以下命令把新域設置成 64m , eden 占 32m ,每個救助域各占 16m :java-xms256m-xmx256m-xmn64m-xx:survivorration=2如前所述, 默認狀態(tài)下hotspot 對新域使用復制收集器, 對舊域使用標記清除壓縮收集器。在新域中使用復制收集器有很多意義,因為應用程序生成的大部分對象是短壽命的。理想狀態(tài)下,所有過渡對象在移出 eden 空間時將被收集。如果能夠這樣的話,并且移出 eden
34、空間的對象是長壽命的,那么理論上可以立即把它們移進舊域,避免在救助空間反復復制。但是,應用程序不能適合這種理想狀態(tài),因為它們有一小部分中長壽命的對象。最好是保持這些中長壽命的對象并放在新域中,因為復制小部分的對象總比壓縮舊域廉價。為控制新域中對象的復制,可用 -xx:targetsurvivorratio 控制救助空間的比例(該值是設置救助空間的使用比例。如救助空間位1m ,該值 50 表示可用 500k )。該值是一個百分比,默認值是 50 。當較大的堆棧使用較低的 sruvivorratio 時,應增加該值到 80 至 90 ,以更好利用救助空間。用-xx:maxtenuringthreshold 可控制上限。為放置所有的復制全部發(fā)生以及希望對象從 eden 擴展到舊域, 可以把 maxtenuringthreshold 設置成 0 。設置完成后,實際上就不再使用救助空間了,因此應把survivorratio 設成最大值以最大化 eden空間,設置如下:java-xx:maxtenuringthreshold=0 xx:survivorratio = 50000 垃圾回收描述:垃圾回收分多級, 0 級為全部 (full) 的
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 保密采購合同范例
- 案例合同范例
- 買更名房合同范例
- 林場產權出售合同范例
- 土地集體流轉合同范例
- 株洲裝飾辦合同范例
- 麗水預售合同范例公示
- 安裝標識標牌合同范例
- 干菜類銷售合同范例
- 平臺推廣合同范例
- 中國文化符號
- 蘇平師生葫蘆絲專場晚會主持詞
- 個案SOAP表-催眠案例記錄表
- 萬用表校準報告
- 物聯(lián)網(wǎng)項目實施進度計劃表
- Unit 4 Lesson 1 Avatars 教案 高中英語新北師大版必修第二冊(2022-2023學年)
- 日積月累 詳細版課件
- 實驗2溶液中金、銀銅的提取及鑒定
- GB∕T 26520-2021 工業(yè)氯化鈣-行業(yè)標準
- 久其報表軟件基本操作流程正式版
- DBJ50∕T-303-2018 玻璃幕墻安全性檢測鑒定技術標準
評論
0/150
提交評論