java 正则 栈溢出_关于Java正则引起的StackOverFlowError问题以及解决方案 | 学步园...
java 正則異常 java.lang.StackOverflowError:
在使用正則表達式的時候,底層是通過迭代方式執行的,每一層的迭代都會在棧線程的大小中占一定內存,如果迭代的層次很多,就會報出stackOverFlowError異常。所以在使用正則的時候其實是有利有弊的。我們使用的weblogic服務器,修改了配置-Xss的大小為512K后,測試幾次沒有報錯。現在修改成了1M,再觀察一段時間。修改-Xss只是治標不治本的解決方法,要從根源上解決還需要優化正則。
以下是從網絡上摘抄的:
根本原因是這樣的,對于每一個線程,都有一個java棧 ,當有一個方法被調用的時候,會產生一些跟這個方法相關的信息,如方法名,參數,中間變量等等,這些叫做棧幀 ,當一個方法執行完畢? 這個棧幀才會從棧頂pop掉? 你遞歸的話? 會一直向棧里push棧幀? 而這個java棧是有一定的長度或深度的,當棧滿了,無法再進行push的時候 就出現你上面的異常了,解決辦法的話 就不要用遞歸操作 改用for 而且平時也不建議用遞歸的,效率太低了 .
參考網址:http://bbs.csdn.net/topics/370099884
棧溢出了,JVM依然是采用棧式的虛擬機,這個和C和Pascal都是一樣的。函數的調用過程都體現在堆棧和退棧上了。你調用構造函數的“層”太多了,以致于把棧區溢出了。
通常來講,一般棧區遠遠小于堆區的,因為函數調用過程往往不會多于上千層,而即便每個函數調用需要1K的空間(這個大約相當于在一個C函數內聲明了256個int類型的變量),那么棧區也不過是需要1MB的空間。通常棧的大小是1-2MB的。通常遞歸也不要遞歸的層次過多,很容易溢出.
參考網址:http://bbs.csdn.net/topics/380047221
對java.lang.StackOverflowError的分析:
原因:運行一個程序,JVM會開辟一塊內存空間去儲存程序進行時的某些信息,當程序運行時需要儲存的信息超過了分配的空間,就會出現那樣的問題.比如死循環,
解決:首先從程序代碼優化方面著手,檢查是否有死循環、遞歸等程序,如果有,修正、優化相關代碼。
參考網址:http://blog.csdn.net/gaomatrix/article/details/6604579
有時regex包中的Pattern類會拋出StackOverflowError.這是已知的bug #5050507的表現,它自從Java 1.4就存在于java.util.regex包中。這個bug仍然存在,因為它是“won't fix”的狀態。這個錯誤的出現是因為,Pattern類把一個正則表達式編譯為一個用來尋找匹配的小程序。這個程序被遞歸調用,有時太多的遞歸就會導致該錯誤的出現。更多細節請參考bug描述。看起來大部分是在使用選擇(alternation)的出現。
參考網址:http://edu.21cn.com/java/g_189_801829-1.htm
大致的描述一下問題,有一個正則匹配,本機環境可以正常匹配,在另一臺服務器也可以正常匹配,但是只有一臺 不行,我就懷疑是那臺機器的環境問題,結果和我想的一樣。
設置jvm參數
Xss 設置成默認即可
參考網址:http://blog.knowsky.com/190676.htm
Java程序中,每個線程都有自己的Stack Space。這個Stack Space不是來自Heap的分配。所以Stack Space的大小不會受到-Xmx和-Xms的影響,這2個JVM參數僅僅是影響Heap的大小。Stack Space用來做方法的遞歸調用時壓入Stack Frame。所以當遞歸調用太深的時候,就有可能耗盡Stack Space,爆出StackOverflow的錯誤。Stack Space的大小隨著OS,JVM以及環境變量的大小而發生變化。一般說來默認的大小是512K。在64位的系統中,這個Stack
Space值會更大。一般說來,Stack Space為128K是夠用的。這時你說需要做的就是觀察。如果你的程序沒有爆出StackOverflow的錯誤,可以使用-Xss來調整Stack Space的大小為128K。(eg:-Xss128K)
參考網址:http://thomaschen2011.iteye.com/blog/1214114
從異常信息來看,很明顯,線程棧空間不足,一般來說,存在這種情況,是因為方法的嵌套調用層次太深,上層的方法棧一直得不到釋放,導致棧空間不足。因為正則匹配的時候,嵌套層次太深,“()”太多太深。請記住一句老話:“ 您有一個問題,用正則表達式解決。那您就有兩個問題了。”
參考網址:http://www.iteye.com/topic/860654
關于:優化Java中的正則表達式
1、如果在程序中多次使用同一個正則表達式,一定要用Pattern.compile()編譯,代替直接使用Pattern.matches()。如果一次次對同一個正則表達式使用Pattern.matches(),例如在循環中,沒有編譯的正則表達式消耗比較大。因為matches()方法每次都會預編譯使用的表達式。另外,記住你可以通過調用reset()方法對不同的輸入字符串重復使用Matcher對象。
2、留意選擇(Beware of alternation)。類似“(X|Y|Z)”的正則表達式有降低速度的壞名聲,所以要多留心。首先,考慮選擇的順序,那么要將比較常用的選擇項放在前面,因此它們可以較快被匹配。另外,嘗試提取共用模式;例如將“(abcd|abef)”替換為“ab(cd|ef)”。后者匹配速度較快,因為NFA會嘗試匹配ab,如果沒有找到就不再嘗試任何選擇項。(在當前情況下,只有兩個選擇項。如果有很多選擇項,速度將會有顯著的提升。)選擇的確會降低程序的速度。在我的測試中,表達式“.*(abcd|efgh|ijkl).*”要比調用String.indexOf()三次——每次針對表達式中的一個選項——慢三倍。
3、獲取每次使用引起小損失的分組。如果你實際并不需要獲取一個分組內的文本,那么就使用非捕獲分組。例如使用“(?:X)”代替“(X)”。
參考網址:http://blog.csdn.net/mydeman/article/details/1800636
(大概的意思就是,如果我們使用遞歸了,首先你得明白什么是遞歸,遞歸就是一個方法被調用N次。當方法被調用的時候,方法的參數,定義等信息會存在本次線程對應的java棧里。一個方法被調用N次,那就得往這個java棧里放N次。次數如果過多,那么java棧就會溢出。)
總結
以上是生活随笔為你收集整理的java 正则 栈溢出_关于Java正则引起的StackOverFlowError问题以及解决方案 | 学步园...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 申购发债有什么好处?发债买了会亏吗
- 下一篇: 微信还信用卡成功但是没到账怎么回事