【发布时间】:2016-06-19 16:09:29
【问题描述】:
我正在生成一个 HashMap,我可以在其中估计阶乘所需的大小:
import scala.collection.mutable.HashMap
val mm = new HashMap [Int, BigInt]
mm.put (0, 1)
def fak (i: Int) : BigInt = mm.getOrElseUpdate (i, i * fak (i-1))
我经常按升序请求素数的阶乘 (fak),并且喜欢达到相当高的值(> 10 个 Mio 阶乘)。
使用大约 70000 调用它会导致 OutOfMemory-Error: Java Heap Space。我用
开始了这个程序scala -J-Xmx4G TestFak 70000
使用 60000 作为参数它可以工作。我猜,它构建了 70000 个 MutableMap,它们经常被丢弃和垃圾收集。既然我提前知道了所需的大小,是否可以从一开始就生成一个合适大小的 mutableMap?
在 mm.getOrElseUpdate - 行中引发错误。
版本: Scala 版本 2.11.6(OpenJDK 64 位服务器 VM,Java 1.8.0_66-internal)
【问题讨论】:
-
它没有构建 70000 个地图,只有一张地图有 70000 个条目。一个没有任何数据的映射条目大约需要 36 个字节,36*70K 大约是 2.5 gig。加上您存储的 BigInts 的实际大小(它们也不小)。你刚刚达到你的内存限制。
-
@Dima:嗯,根据快速估计,36*70K应该是2.5M左右,不是2.5G吧?
-
是的,你是对的 :) YourKit?
-
您只需要存储主要的,对吧?为什么不扔掉 p(n-1) 和 p(n) 之间的所有非质数,一旦你命中 p(n)?
-
@RexKerr:事实上,我需要的不仅仅是主要的。大约 50% 的数字,最终达到 1 亿,所以任何让我得到 2 倍或 10 倍的技巧都不够。同时我试图只存储最后一个数字,但即使这种方法也很慢。乐观地说,它会在 2 天而不是 1 分钟内运行。 :) 既然是测验,我不想问根本问题,这似乎需要一些更多的数学方法。但要么我自己解决这个问题,要么就一直没有解决。
标签: scala heap-memory mutablemap