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

Popular posts from this blog

PHP DOM loadHTML() method unusual warning -

python - How to create jsonb index using GIN on SQLAlchemy? -

c# - TransactionScope not rolling back although no complete() is called -