【问题标题】:Heap Space with mutable.HashMap带有 mutable.HashMap 的堆空间
【发布时间】: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


【解决方案1】:

70000 的阶乘是巨大的!存储所需的BigInt 本身将相当大!只是为了给您一个想法,BigInt 可能由 Java 中的Array[Int] 支持。这意味着存储 1!, 2!, ..., 70000! 所需的总大小!对于n = 70000,将是sum_(1 to n) of 4 * log_(2^32) n!,大约为4 GB。

【讨论】:

  • 是的,这听起来很合理。我已经监督过了。由于我必须使用高达 1 亿的阶乘,我必须找到另一种方法来解决挑战,这就是其中的一部分。 :)
  • 糟糕,我的数学有点错误。整数是 4 个字节而不是 8 个。
  • 另外,为什么不试试普通的尾递归方法呢?没那么慢……
  • 好吧nvm...普通的尾递归解决方案太慢了。
猜你喜欢
  • 2012-10-18
  • 2010-10-17
  • 1970-01-01
  • 1970-01-01
  • 2018-05-27
  • 1970-01-01
  • 1970-01-01
  • 2013-01-03
  • 1970-01-01
相关资源
最近更新 更多