【发布时间】:2014-03-21 01:20:30
【问题描述】:
我写了一个函数,给定一个Stream[Long],它将过滤掉> 4,000,000的数字。
def filterLt4Mil(xs: Stream[Long]) = {
@tailrec
def go(xs: Stream[Long], acc: Stream[Long]): Stream[Long] = xs match {
case Stream() => acc
case a #:: as if(a < 4000000L) => go(as, acc :+ a)
case a #:: as if(a > 4000000L) => go(as, acc)
}
go(xs, Stream[Long]())
}
但是,当传入一个范围从 0 到 10,000,000 百万的 Stream 时,我得到一个 OutOfMemoryException。
scala> val x = Stream.range(0,10000000L)
x: scala.collection.immutable.Stream[Long] = Stream(0, ?)
scala> filterLt4Mil(x)
java.lang.OutOfMemoryError: GC overhead limit exceeded
at scala.collection.immutable.List.toStream(List.scala:312)
由于filterLt4Mil 使用了尾调用优化,我的理解是堆栈不应该溢出。
但是,为什么会出现 OutOfMemoryException?如何预防?
【问题讨论】:
-
如果省略 val x = 行会发生什么(即,将其写为 filterLt4Mil(Stream.range(0,10000000L))?