Scala unexpected stack overflow
I've written this basic program in Scala :
import scala.collection.mutable.HashMap
object HelloWorld {
val treasureMap = new HashMap[BigInt, BigInt]
def main(args: Array[String]) {
println(fibCache(10))
}
def fibCache(n: BigInt): BigInt = {
if (n == 0 || n == 1) {
return n
}
return treasureMap.getOrElseUpdate(n, fibCache(n - 1) + fibCache(n - 2))
}
}
and I would expect that with really large values, I'd have an OutOfMemoryError or something, but instead I see this:
Exception in thread "main" java.lang.StackOverflowError
at java.math.BigInteger.compareMagnitude(Unknown Source)
at java.math.BigInteger.compareTo(Unknown Source)
at scala.math.BigInt.compare(BigInt.scala:141)
at scala.math.BigInt.$less$eq(BigInt.scala:145)
at scala.math.BigInt.fitsInLong(BigInt.scala:130)
at scala.math.BigInt.hashCode(BigInt.scala:120)
at scala.runtime.BoxesRunTime.hashFromNumber(Unknown Source)
at scala.collection.mutable.HashTable$HashUtils$class.elemHashCode(HashTable.scala:366)
at scala.collection.mutable.HashMap.elemHashCode(HashMap.scala:43)
at scala.collection.mutable.HashTable$class.findEntry(HashTable.scala:108)
at scala.collection.mutable.HashMap.findEntry(HashMap.scala:43)
at scala.collection.mutable.HashMap.get(HashMap.scala:63)
at scala.collection.mutable.MapLike$class.getOr开发者_C百科ElseUpdate(MapLike.scala:186)
at scala.collection.mutable.HashMap.getOrElseUpdate(HashMap.scala:43)
Can someone help explain why? Also, is there a runtime setting I can use to alleviate this? Will -Xss help?
A StackOverflowError is a variation on the theme of running out of memory, it's just being precise about exactly which memory area has run out.
So yes, -Xss
will help, but there's a better way....
This page has several alternative implementations that you can try: http://en.literateprograms.org/Fibonacci_numbers_(Scala)
You'll want to use the tail-recursive or stream-based variant to keep the stack size down.
精彩评论