遞歸調用 VS 循環調用

現象java

有一個方法 邏輯以下oop

  • 分批查詢state=0的數據 每次500條
  • 作一些處理後 修改state狀態 state=0 ==> state=1 表示已經處理過了
  • 遞歸調用 直到查不出數據來

發現當數據量大的時候 若有幾萬條數據待處理 很容易發生內存溢出的問題 以爲很奇怪 不是每次限制只查500條嗎 怎麼還會有內存溢出的問題呢?spa

假設
遞歸調用不會釋放局部變量 直到方法調用結束code

證實遞歸

@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 此時能夠無限執行下去方法

相關文章
相關標籤/搜索