Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 意外的堆栈溢出_Scala_Stack Overflow - Fatal编程技术网

Scala 意外的堆栈溢出

Scala 意外的堆栈溢出,scala,stack-overflow,Scala,Stack Overflow,我用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 ||

我用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))
  }
}
我希望对于非常大的值,我会有OutOfMemoryError或其他什么,但我看到的是:

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.getOrElseUpdate(MapLike.scala:186)
    at scala.collection.mutable.HashMap.getOrElseUpdate(HashMap.scala:43)

有人能解释一下原因吗?还有,我是否可以使用运行时设置来缓解这种情况?-Xss会有帮助吗?

StackOverflower错误是关于内存耗尽主题的一个变体,它只是精确地说明哪个内存区域已经耗尽

所以,是的,
-Xss
会有所帮助,但有更好的方法

此页面有几个可供选择的实现,您可以尝试:


您需要使用尾部递归或基于流的变体来降低堆栈大小。

刚刚在我的机器(3GB Macbook)上用最新版本的scala运行了它,它按预期运行。您使用了多大的值?结果是什么?32/64位、可用物理内存和-Xss参数都会影响问题发生的确切点,因此不要担心实际选择的数字。根据您的配置,知道这会在某个时候爆发就足够了。我很熟悉StackOverflow是什么。当我用Java编写这个等价物时,情况并非如此。在清理堆栈之前,它会耗尽内存。@阿米尔Scala发出的代码倾向于比Java代码更依赖于堆栈。特别是如果您是以更具功能性的风格编写,或者通过使用包装Java标准库中的方法的Scala方法向堆栈添加两个级别。我不会让你担心的,我明白了。谢谢你的评论。尾部递归实现是如何保持堆栈大小的?基于jvm的语言(如scala、clojure)不进行尾部调用优化,因为jvm不支持它。@Babu jvm不进行尾部调用优化。斯卡拉有。