BigInteger memory leak causes stack overflow in Java -
i trying write optimized fibonacci assignment able compute fib(300) , fib(8000). here have far (map hashmap).
public static biginteger fibmemo(int n) { if (n <= 1){ return biginteger.valueof(n); } if (!map.containskey(n)){ map.put(n, fibmemo(n-1).add(fibmemo(n-2))); } return map.get(n); }
when call
system.out.println("300: " + fibonaccimemo.fibmemo(300));
on own, works fine. also,
system.out.println("8000: " + fibonaccimemo.fibmemo(8000));
works fine if comment out previous call fib(300). if keep both calls stack overflow on recursive fibmemo. seems strange me. please clarify situation? in advance.
here code:
import java.util.hashmap; // import java's hashmap can use import java.math.biginteger; public class fibonaccimemo { private static hashmap<integer, biginteger> map = new hashmap<integer, biginteger>(); /** * classic recursive implementation no memoization. don't care * graceful error catching, we're interested in performance. * * @param n * @return nth fibonacci number */ public static int fibnomemo(int n) { if (n <= 1) { return n; } return fibnomemo(n - 2) + fibnomemo(n - 1); } /** * optimized recursive implementation memoization. * may assume n non-negative. * * @param n * @return nth fibonacci number */ public static biginteger fibmemo(int n) { // code here if (n <= 1){ return biginteger.valueof(n); } if (!map.containskey(n)){ map.put(n, fibmemo(n-1).add(fibmemo(n-2))); } return map.get(n); } public static void main(string[] args) { // optional testing here string m = "fibonacci's real name leonardo pisano bigollo."; m += "\n" + "he son of wealthy merchant.\n"; system.out.println(m); system.out.println("300: " + fibonaccimemo.fibmemo(300)); system.out.println("8000: " + fibonaccimemo.fibmemo(8000)); // 46th fibonacci = 1,836,311,903 // 47th fibonacci = 2,971,215,073 } }
there 2 problems code. obvious 1 stack consumption. memoization reduce time complexity exponential linear, still, method has linear stack consumption - input value of 8000, allocates 8000 stack frames.
as stated in docs, default stack size per thread 320kb, suffices 1000 - 2000 frames, not enough. increase stack size using -xss
jvm switch, still not bullet proof. should use iterative implementation instead.
the second problem static cache never cleared, causes memory leak. either wrap recursive method in 1 clears hashmap after recursion terminates, throws away bit of performance, because results of 1 invocation cannot reused in following ones.
a more performant solution use proper cache implementation doesn't require manual cleaning, handles size limits , garbage collection on own. guava provides such implementation.
Comments
Post a Comment