java記憶體溢位 棧溢位的原因與排查方法
1、 記憶體溢位的原因是什麼?
記憶體溢位是由於沒被引用的物件(垃圾)過多造成JVM沒有及時回收,造成的記憶體溢位。如果出現這種現象可行程式碼排查:
一)是否App中的類中和引用變數過多使用了Static修飾 如public staitc Student s;在類中的屬性中使用 static修飾的最好只用基本型別或字串。如public static int i = 0; //public static String str;
二)是否App中使用了大量的遞迴或無限遞迴(遞迴中用到了大量的建新的物件)
三)是否App中使用了大量迴圈或死迴圈(迴圈中用到了大量的新建的物件)
四)檢查App中是否使用了向資料庫查詢所有記錄的方法。即一次性全部查詢的方法,如果資料量超過10萬多條了,就可能會造成記憶體溢位。所以在查詢時應採用“分頁查詢”。
五)檢查是否有陣列,List,Map中存放的是物件的引用而不是物件,因為這些引用會讓對應的物件不能被釋放。會大量儲存在記憶體中。
六)檢查是否使用了“非字面量字串進行+”的操作。因為String類的內容是不可變的,每次執行"+"就會產生新的物件,如果過多會造成新String物件過多,從而導致JVM沒有及時回收而出現記憶體溢位。
如String s1 = "My name";
String s2 = "is";
String s3 = "xuwei";
String str = s1 + s2 + s3 +.........;這是會容易造成記憶體溢位的
但是String str = "My name" + " is " + " xuwei" + " nice " + " to " + " meet you"; //但是這種就不會造成記憶體溢位。因為這是”字面量字串“,在執行"+"時就會在編譯期間執行好。不會按照JVM來執行的。
在使用String,StringBuffer,StringBuilder時,如果是字面量字串進行"+"時,應選用String效能更好;如果是String類進行"+"時,在不考慮執行緒安全時,應選用StringBuilder效能更好。
七)使用 DDMS工具進行查詢記憶體溢位的大概位置
2、棧溢位的原因
一)、是否有遞迴呼叫
二)、是否有大量迴圈或死迴圈
三)、全域性變數是否過多
四)、 陣列、List、map資料是否過大
五)使用DDMS工具進行查詢大概出現棧溢位的位置