首先先說一下JVM內(nèi)存結(jié)構(gòu)問題,JVM為兩塊:PermanentSapce和HeapSpace,其中\(zhòng)x0d\x0aHeap = }。PermantSpace負(fù)責(zé)保存反射對象,一般不用配置。JVM的Heap區(qū)可以通過-X參數(shù)來設(shè)定。\x0d\x0a 當(dāng)一個URL被訪問時,內(nèi)存申請過程如下:\x0d\x0aA. JVM會試圖為相關(guān)Java對象在Eden中初始化一塊內(nèi)存區(qū)域\x0d\x0aB. 當(dāng)Eden空間足夠時,內(nèi)存申請結(jié)束。否則到下一步\x0d\x0aC. JVM試圖釋放在Eden中所有不活躍的對象(這屬于1或更高級的垃圾回收), 釋放后若Eden空間仍然不足以放入新對象,則試圖將部分Eden中活躍對象放入Survivor區(qū)\x0d\x0aD. Survivor區(qū)被用來作為Eden及OLD的中間交換區(qū)域,當(dāng)OLD區(qū)空間足夠時,Survivor區(qū)的對象會被移到Old區(qū),否則會被保留在Survivor區(qū)\x0d\x0aE. 當(dāng)OLD區(qū)空間不夠時,JVM會在OLD區(qū)進(jìn)行完全的垃圾收集(0級)\x0d\x0aF. 完全垃圾收集后,若Survivor及OLD區(qū)仍然無法存放從Eden復(fù)制過來的部分對象,導(dǎo)致JVM無法在Eden區(qū)為新對象創(chuàng)建內(nèi)存區(qū)域,則出現(xiàn)”out of memory錯誤”\x0d\x0a\x0d\x0aJVM調(diào)優(yōu)建議:\x0d\x0a\x0d\x0ams/mx:定義YOUNG+OLD段的總尺寸,ms為JVM啟動時YOUNG+OLD的內(nèi)存大??;mx為最大可占用的YOUNG+OLD內(nèi)存大小。在用戶生產(chǎn)環(huán)境上一般將這兩個值設(shè)為相同,以減少運(yùn)行期間系統(tǒng)在內(nèi)存申請上所花的開銷。\x0d\x0aNewSize/MaxNewSize:定義YOUNG段的尺寸,NewSize為JVM啟動時YOUNG的內(nèi)存大?。籑axNewSize為最大可占用的YOUNG內(nèi)存大小。在用戶生產(chǎn)環(huán)境上一般將這兩個值設(shè)為相同,以減少運(yùn)行期間系統(tǒng)在內(nèi)存申請上所花的開銷。\x0d\x0aPermSize/MaxPermSize:定義Perm段的尺寸,PermSize為JVM啟動時Perm的內(nèi)存大小;MaxPermSize為最大可占用的Perm內(nèi)存大小。在用戶生產(chǎn)環(huán)境上一般將這兩個值設(shè)為相同,以減少運(yùn)行期間系統(tǒng)在內(nèi)存申請上所花的開銷。\x0d\x0aSurvivorRatio:設(shè)置Survivor空間和Eden空間的比例\x0d\x0a\x0d\x0a內(nèi)存溢出的可能性\x0d\x0a\x0d\x0a1. OLD段溢出\x0d\x0a這種內(nèi)存溢出是最常見的情況之一,產(chǎn)生的原因可能是:\x0d\x0a1) 設(shè)置的內(nèi)存參數(shù)過小(ms/mx, NewSize/MaxNewSize)\x0d\x0a2) 程序問題\x0d\x0a單個程序持續(xù)進(jìn)行消耗內(nèi)存的處理,如循環(huán)幾千次的字符串處理,對字符串處理應(yīng)建議使用StringBuffer。此時不會報內(nèi)存溢出錯,卻會使系統(tǒng)持續(xù)垃圾收集,無法處理其它請求,相關(guān)問題程序可通過Thread Dump獲取(見系統(tǒng)問題診斷一章)單個程序所申請內(nèi)存過大,有的程序會申請幾十乃至幾百兆內(nèi)存,此時JVM也會因無法申請到資源而出現(xiàn)內(nèi)存溢出,對此首先要找到相關(guān)功能,然后交予程序員修改,要找到相關(guān)程序,必須在Apache日志中尋找。\x0d\x0a當(dāng)Java對象使用完畢后,其所引用的對象卻沒有銷毀,使得JVM認(rèn)為他還是活躍的對象而不進(jìn)行回收,這樣累計占用了大量內(nèi)存而無法釋放。由于目前市面上還沒有對系統(tǒng)影響小的內(nèi)存分析工具,故此時只能和程序員一起定位。\x0d\x0a\x0d\x0a2. Perm段溢出\x0d\x0a通常由于Perm段裝載了大量的Servlet類而導(dǎo)致溢出,目前的解決辦法:\x0d\x0a1) 將PermSize擴(kuò)大,一般256M能夠滿足要求\x0d\x0a2) 若別無選擇,則只能將servlet的路徑加到CLASSPATH中,但一般不建議這么處理\x0d\x0a\x0d\x0a3. C Heap溢出\x0d\x0a系統(tǒng)對C Heap沒有限制,故C Heap發(fā)生問題時,Java進(jìn)程所占內(nèi)存會持續(xù)增長,直到占用所有可用系統(tǒng)內(nèi)存\x0d\x0a\x0d\x0a參數(shù)說明:\x0d\x0a\x0d\x0aJVM 堆內(nèi)存(heap)設(shè)置選項 \x0d\x0a 參數(shù)格式 \x0d\x0a 說 明 \x0d\x0a \x0d\x0a設(shè)置新對象生產(chǎn)堆內(nèi)存(Setting the Newgeneration heap size) \x0d\x0a -XX:NewSize \x0d\x0a 通過這個選項可以設(shè)置Java新對象生產(chǎn)堆內(nèi)存。在通常情況下這個選項的數(shù)值為1 024的整數(shù)倍并且大于1MB。這個值的取值規(guī)則為,一般情況下這個值-XX:NewSize是最大堆內(nèi)存(maximum heap size)的四分之一。增加這個選項值的大小是為了增大較大數(shù)量的短生命周期對象 \x0d\x0a\x0d\x0a增加Java新對象生產(chǎn)堆內(nèi)存相當(dāng)于增加了處理器的數(shù)目。并且可以并行地分配內(nèi)存,但是請注意內(nèi)存的垃圾回收卻是不可以并行處理的 \x0d\x0a \x0d\x0a設(shè)置最大新對象生產(chǎn)堆內(nèi)存(Setting the maximum New generation heap size) \x0d\x0a -XX:MaxNewSize \x0d\x0a 通過這個選項可以設(shè)置最大Java新對象生產(chǎn)堆內(nèi)存。通常情況下這個選項的數(shù)值為1 024的整數(shù)倍并且大于1MB \x0d\x0a\x0d\x0a其功用與上面的設(shè)置新對象生產(chǎn)堆內(nèi)存-XX:NewSize相同\x0d\x0a\x0d\x0a設(shè)置新對象生產(chǎn)堆內(nèi)存的比例(Setting New heap size ratios) \x0d\x0a -XX:SurvivorRatio \x0d\x0a 新對象生產(chǎn)區(qū)域通常情況下被分為3個子區(qū)域:伊甸園,與兩個殘存對象空間,這兩個空間的大小是相同的。通過用-XX:SurvivorRatio=X選項配置伊甸園與殘存對象空間(Eden/survivor)的大小的比例。你可以試著將這個值設(shè)置為8,然后監(jiān)控、觀察垃圾回收的工作情況\x0d\x0a\x0d\x0a設(shè)置堆內(nèi)存池的最大值(Setting maximum heap size) \x0d\x0a -Xmx \x0d\x0a 通過這個選項可以要求系統(tǒng)為堆內(nèi)存池分配內(nèi)存空間的最大值。通常情況下這個選項的數(shù)值為1 024的整數(shù)倍并且大于1 MB \x0d\x0a\x0d\x0a一般情況下這個值(-Xmx)與最小堆內(nèi)存(minimum heap size _Xms)相同,以降低垃圾回收的頻度 \x0d\x0a \x0d\x0a取消垃圾回收 \x0d\x0a -Xnoclassgc \x0d\x0a 這個選項用來取消系統(tǒng)對特定類的垃圾回收。它可以防止當(dāng)這個類的所有引用丟失之后,這個類仍被引用時不會再一次被重新裝載,因此這個選項將增大系統(tǒng)堆內(nèi)存的空間 \x0d\x0a \x0d\x0a設(shè)置棧內(nèi)存的大小 \x0d\x0a -Xss \x0d\x0a 這個選項用來控制本地線程棧的大小,當(dāng)這個選項被設(shè)置的較大(2MB)時將會在很大程度上降低系統(tǒng)的性能。因此在設(shè)置這個值時應(yīng)該格外小心,調(diào)整后要注意觀察系統(tǒng)的性能,不斷調(diào)整以期達(dá)到最優(yōu) \x0d\x0a \x0d\x0a最后說一句,你的機(jī)器的連接數(shù)設(shè)置也至關(guān)重要,連接的關(guān)閉最好把時間設(shè)置的少些,那些連接非常耗費(fèi)資源。也是引起內(nèi)存泄露的主要原因。

成都創(chuàng)新互聯(lián)公司是一家專業(yè)提供定興企業(yè)網(wǎng)站建設(shè),專注與成都網(wǎng)站建設(shè)、網(wǎng)站建設(shè)、H5技術(shù)、小程序制作等業(yè)務(wù)。10年已為定興眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)絡(luò)公司優(yōu)惠進(jìn)行中。
Java堆棧溢出的出現(xiàn) 很讓人痛苦的事情 很多時候都無法找到頭緒 這里作者通過使用jrockit調(diào)用程序才最終發(fā)現(xiàn)了問題的所在 在很多情況下 Java堆棧溢出 很有可能是你的代碼中用到數(shù)組 到你的索引超出范圍了
java lang OutOfMemoryError: Java heap space
在Java程序運(yùn)行中可能會報如上的錯誤 通常是在運(yùn)行過程中內(nèi)存占用了沒有別釋放造成的
以前可能沒法跟蹤可能是很痛苦的事情 現(xiàn)在好了 我們有一個調(diào)試軟件可以用了 在生產(chǎn)環(huán)境下使用的jRockit軟件進(jìn)行調(diào)試 是Oracle公司出品的
前兩天試用了一下真的很不錯
前陣子有個程序跑 個禮拜左右就會出現(xiàn)Java堆棧溢出 始終找不到頭緒 后來使用jrockit才找到問題的出處
jrockit是可以調(diào)試遠(yuǎn)程程序也可以調(diào)試本地程序的
具體調(diào)試步驟
(一)
如果是調(diào)試本地程序的話 啟動jrockit 然后啟動本地需要調(diào)試的程序 會在左側(cè)工具欄 本地目錄下創(chuàng)建一個連接為需要調(diào)試的程序 在上面點(diǎn)擊右鍵 就會啟動跟蹤
如何跟蹤呢 我的辦法就是等 在跟蹤開始后 進(jìn)行截圖 然后等程序運(yùn)行一段時間后查找堆增長比較大的并且一直沒有釋放的變量
(二)
然后在上面點(diǎn)擊右鍵 顯示分配跟蹤
(三)
然后找到對應(yīng)的方法 然后就去找問題吧 看看是不是那個地方有內(nèi)存一直沒有釋放啊
然后說點(diǎn)我自己的小經(jīng)驗(yàn) 也許是不對的 但是我在我的應(yīng)用里面確實(shí)是有效的
在經(jīng)常需要調(diào)用的地方將變量設(shè)成全局的甚至是靜態(tài)的 我的操作是設(shè)成全局的了 圖省事呢 呵呵 因?yàn)槲业淖兞繒r全局都要調(diào)用的而且是頻繁調(diào)用的
用完的變量一定要記得讓它等于null 否則執(zhí)行g(shù)c()貌似是不給回收的
基本上jrockit跟蹤是很強(qiáng)的 都能夠找到你的問題所在 要仔細(xì)觀察 改完程序后記得再重新跟蹤下直到?jīng)]有內(nèi)存泄露為止
寫完手工
lishixinzhi/Article/program/Java/hx/201311/26094
程序邏輯中永遠(yuǎn)跳不出遞歸調(diào)用,因?yàn)樵趖est中所有邏輯分支中都是往下遞歸調(diào)用,沒有終止的邏輯步驟。和方法自己調(diào)用自己沒有區(qū)別。
需要在某個邏輯分支中返回(終止遞歸)。
調(diào)整虛擬機(jī)參數(shù),加大heap space 的大小 或者 分批獲取數(shù)據(jù)。
虛擬機(jī)參數(shù)配置的話可以參考:
-Xms1024m -Xmx1024m -Xmn300m -XX:PermSize=64m -XX:MaxPermSize=128m
具體配置項含義建議去網(wǎng)上查查。不管你是使用本地應(yīng)用還是web應(yīng)用都可以配置的。
新聞名稱:堆溢出的代碼Java 堆溢出的原因及解決辦法
文章出自:http://www.jbt999.com/article22/hjjdjc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)頁設(shè)計公司、商城網(wǎng)站、外貿(mào)網(wǎng)站建設(shè)、做網(wǎng)站、企業(yè)網(wǎng)站制作、外貿(mào)建站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:[email protected]。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)