也许,你想到了个补救方法来挽救程序2,就是每次在处理完list后,我把它设置为null,不让栈帧继续引用着它,咱编写对gc友好的代码,这不就行了,试试:
import java.util.ArrayList; import java.util.List; public class TailRecursionTest2 { public static void main(String[] args) { TailRecursionTest2 t = new TailRecursionTest2(); t.a(0); } public void a(int j) { System.out.println(j); j++; if (j == 10000) return; List list = new ArrayList<Integer>(100000); // 对list进行处理 list = null; //gc友好 a(j); } } |
得意洋洋,我跑一下看看,这次跑到4000多次,但是:
4289 4290 4291 4292 java.lang.StackOverflowError at sun.nio.cs.ext.DoubleByteEncoder.encodeArrayLoop(Unknown Source) at sun.nio.cs.ext.DoubleByteEncoder.encodeLoop(Unknown Source) at java.nio.charset.CharsetEncoder.encode(Unknown Source) |
总结:在java里,递归最好咱还是别用,老老实实地while、for;就算递归了,最好递归方法不要new太大的对象,除非你能确定递归的深度不是那么大,否则OOM和堆栈溢出的阴影将笼罩着你。