 在開發時,要注意避免該問題,特別是遞歸過多調用時,最好改為for或者whlie來代替。如下cycle()方法:[java] view plain copypublic static void cycle(int totalTimes, int time)  {      if(totalTimes > 1)      {          System.out.println("這是第 " +  time + "次調用!");      }      else      {          System.out.println("調用結束,共調用了" + time + "次");      }  }  代替recuresion()方法:[java] view plain copypublic static void recursion(int totalTimes,int time)      {          if(totalTimes > 1)          {              System.out.println("這是第 " +  time + "次調用!");              totalTimes--;              time++;              recursion(totalTimes, time);          }          else          {              System.out.println("調用結束,共調用了" + time + "次");              return;          }      }  [java] view plain copy  再看一下對程序執行效率的影響:仍然使用上面的例子,分別cycle()方法和在main()方法中加入如下代碼:[java] view plain copystartTime = System.currentTimeMillis();  System.out.println("循環調用起始時間:" + startTime);  for (int index = totalTimes; index > 0; index--)  {      cycle(index, time);      time++;  }  System.out.println("循環調用結束時間:" + System.currentTimeMillis());  System.out.println("總耗時:" + (System.currentTimeMillis() - startTime));  System.out.println("--------------------  整個代碼如下:[java] view plain copypublic class RecursionTest  {        public static void recursion(int totalTimes,int time)      {          if(totalTimes > 1)          {              System.out.println("這是第 " +  time + "次調用!");              totalTimes--;              time++;              recursion(totalTimes, time);          }          else          {              System.out.println("調用結束,共調用了" + time + "次");              return;          }      }            public static void cycle(int totalTimes, int time)      {          if(totalTimes > 1)          {              System.out.println("這是第 " +  time + "次調用!");          }          else          {              System.out.println("調用結束,共調用了" + time + "次");          }      }            public static void main(String[] args)      {          int totalTimes = 100000;          int time = 1;          long startTime = System.currentTimeMillis();          System.out.println("嵌套調用起始時間:" + startTime);          recursion(totalTimes, time);          System.out.println("嵌套調用結束時間:" + System.currentTimeMillis());          System.out.println("總耗時:" + (System.currentTimeMillis() - startTime));          System.out.println("------------------------------------------------------------");                    startTime = System.currentTimeMillis();          System.out.println("循環調用起始時間:" + startTime);          for (int index = totalTimes; index > 0; index--)          {              cycle(index, time);              time++;          }          System.out.println("循環調用結束時間:" + System.currentTimeMillis());          System.out.println("總耗時:" + (System.currentTimeMillis() - startTime));          System.out.println("------------------------------------------------------------");      }    }  分別測試totalTimes為500,1000,3000對比結果:500次:
在開發時,要注意避免該問題,特別是遞歸過多調用時,最好改為for或者whlie來代替。如下cycle()方法:[java] view plain copypublic static void cycle(int totalTimes, int time)  {      if(totalTimes > 1)      {          System.out.println("這是第 " +  time + "次調用!");      }      else      {          System.out.println("調用結束,共調用了" + time + "次");      }  }  代替recuresion()方法:[java] view plain copypublic static void recursion(int totalTimes,int time)      {          if(totalTimes > 1)          {              System.out.println("這是第 " +  time + "次調用!");              totalTimes--;              time++;              recursion(totalTimes, time);          }          else          {              System.out.println("調用結束,共調用了" + time + "次");              return;          }      }  [java] view plain copy  再看一下對程序執行效率的影響:仍然使用上面的例子,分別cycle()方法和在main()方法中加入如下代碼:[java] view plain copystartTime = System.currentTimeMillis();  System.out.println("循環調用起始時間:" + startTime);  for (int index = totalTimes; index > 0; index--)  {      cycle(index, time);      time++;  }  System.out.println("循環調用結束時間:" + System.currentTimeMillis());  System.out.println("總耗時:" + (System.currentTimeMillis() - startTime));  System.out.println("--------------------  整個代碼如下:[java] view plain copypublic class RecursionTest  {        public static void recursion(int totalTimes,int time)      {          if(totalTimes > 1)          {              System.out.println("這是第 " +  time + "次調用!");              totalTimes--;              time++;              recursion(totalTimes, time);          }          else          {              System.out.println("調用結束,共調用了" + time + "次");              return;          }      }            public static void cycle(int totalTimes, int time)      {          if(totalTimes > 1)          {              System.out.println("這是第 " +  time + "次調用!");          }          else          {              System.out.println("調用結束,共調用了" + time + "次");          }      }            public static void main(String[] args)      {          int totalTimes = 100000;          int time = 1;          long startTime = System.currentTimeMillis();          System.out.println("嵌套調用起始時間:" + startTime);          recursion(totalTimes, time);          System.out.println("嵌套調用結束時間:" + System.currentTimeMillis());          System.out.println("總耗時:" + (System.currentTimeMillis() - startTime));          System.out.println("------------------------------------------------------------");                    startTime = System.currentTimeMillis();          System.out.println("循環調用起始時間:" + startTime);          for (int index = totalTimes; index > 0; index--)          {              cycle(index, time);              time++;          }          System.out.println("循環調用結束時間:" + System.currentTimeMillis());          System.out.println("總耗時:" + (System.currentTimeMillis() - startTime));          System.out.println("------------------------------------------------------------");      }    }  分別測試totalTimes為500,1000,3000對比結果:500次:
 1000次:
1000次:
 3000次:
3000次:
 以下是從網絡上摘抄的:根本原因是這樣的,對于每一個線程,都有一個java棧 ,當有一個方法被調用的時候,會產生一些跟這個方法相關的信息,如方法名,參數,中間變量等等,這些叫做棧幀 ,當一個方法執行完畢  這個棧幀才會從棧頂pop掉  你遞歸的話  會一直向棧里push棧幀  而這個java棧是有一定的長度或深度的,當棧滿了,無法再進行push的時候 就出現你上面的異常了,解決辦法的話 就不要用遞歸操作 改用for 而且平時也不建議用遞歸的,效率太低了 .  棧溢出了,JVM依然是采用棧式的虛擬機,這個和C和Pascal都是一樣的。函數的調用過程都體現在堆棧和退棧上了。你調用構造函數的“層”太多了,以致于把棧區溢出了。  通常來講,一般棧區遠遠小于堆區的,因為函數調用過程往往不會多于上千層,而即便每個函數調用需要1K的空間(這個大約相當于在一個C函數內聲明了256個int類型的變量),那么棧區也不過是需要1MB的空間。通常棧的大小是1-2MB的。通常遞歸也不要遞歸的層次過多,很容易溢出.   對java.lang.StackOverflowError的分析:  原因:運行一個程序,JVM會開辟一塊內存空間去儲存程序進行時的某些信息,當程序運行時需要儲存的信息超過了分配的空間,就會出現那樣的問題.比如死循環,  解決:首先從程序代碼優化方面著手,檢查是否有死循環、遞歸等程序,如果有,修正、優化相關代碼。
以下是從網絡上摘抄的:根本原因是這樣的,對于每一個線程,都有一個java棧 ,當有一個方法被調用的時候,會產生一些跟這個方法相關的信息,如方法名,參數,中間變量等等,這些叫做棧幀 ,當一個方法執行完畢  這個棧幀才會從棧頂pop掉  你遞歸的話  會一直向棧里push棧幀  而這個java棧是有一定的長度或深度的,當棧滿了,無法再進行push的時候 就出現你上面的異常了,解決辦法的話 就不要用遞歸操作 改用for 而且平時也不建議用遞歸的,效率太低了 .  棧溢出了,JVM依然是采用棧式的虛擬機,這個和C和Pascal都是一樣的。函數的調用過程都體現在堆棧和退棧上了。你調用構造函數的“層”太多了,以致于把棧區溢出了。  通常來講,一般棧區遠遠小于堆區的,因為函數調用過程往往不會多于上千層,而即便每個函數調用需要1K的空間(這個大約相當于在一個C函數內聲明了256個int類型的變量),那么棧區也不過是需要1MB的空間。通常棧的大小是1-2MB的。通常遞歸也不要遞歸的層次過多,很容易溢出.   對java.lang.StackOverflowError的分析:  原因:運行一個程序,JVM會開辟一塊內存空間去儲存程序進行時的某些信息,當程序運行時需要儲存的信息超過了分配的空間,就會出現那樣的問題.比如死循環,  解決:首先從程序代碼優化方面著手,檢查是否有死循環、遞歸等程序,如果有,修正、優化相關代碼。  新聞熱點
疑難解答