現象
有一個方法 邏輯如下
- 分批查詢state=0的資料 每次500條
- 做一些處理後 修改state狀態 state=0 ==> state=1 表示已經處理過了
- 遞迴呼叫 直到查不出資料來
發現當資料量大的時候 如有幾萬條資料待處理 很容易發生記憶體溢位的問題 覺得很奇怪 不是每次限制只查500條嗎 怎麼還會有記憶體溢位的問題呢?
假設
遞迴呼叫不會釋放區域性變數 直到方法呼叫結束
證明
@Test
public void recursiveCall(){
foo(1);
}
private void foo(int i){
// 區域性變數 佔用1M
byte[] a = new byte[1 * 1024 * 1024];
System.out.println(i+" "+a.length);
foo(i+1);
}
當指定最大堆記憶體50M (-Xmx50M
)的時候 遞迴呼叫到40次左右的時候 便會發生記憶體溢位異常
40 1048576
java.lang.OutOfMemoryError: Java heap space
可知遞迴呼叫並未釋放變數a的記憶體佔用
解決
改成迴圈呼叫即可
@Test
public void loopCall(){
bar();
}
private void bar(){
int index = 1;
while (true) {
byte[] a = new byte[1 * 1024 * 1024];
System.out.println(index+" "+a.length);
index ++;
}
}
同樣設定-Xmx50M
此時可以無限執行下去