【问题标题】:Is there a way to limit the memory, ghci can have?有没有办法限制内存,ghci可以有吗?
【发布时间】:2010-09-22 05:53:13
【问题描述】:

我习惯于使用 ghci 调试我的代码。通常,会发生这样的事情(当然不是那么明显):

ghci> let f@(_:x) = 0:1:zipWith(+)f x
ghci> length f

然后,一段时间内什么都没有发生,如果我反应不够快,ghci 可能会吃掉 2 GB 的 RAM,导致我的系统死机。如果为时已晚,解决此问题的唯一方法是 [ALT] + [PRINT] + [K]。

我的问题:有没有一种简单的方法可以将 ghci 可以消耗的内存限制为 1 GB?如果超出限制,则应终止计算或终止 ghci。

【问题讨论】:

标签: debugging haskell memory-management ghc ghci


【解决方案1】:

实现此目的的一种独立于平台的方法是像这样向 Haskell 运行时提供 -M 选项作为 on 选项

ghci +RTS -M1m

详情请参阅the GHC documentation’s page on how to control the RTS (runtime system)

ghci 输出现在看起来像:

>ghci +RTS -M10m
GHCi, version 6.12.3: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package ffi-1.0 ... linking ... done.
Prelude> let f@(_:x) = 0:1:zipWith(+)f x
Prelude> length f
Heap exhausted;
Current maximum heap size is 10485760 bytes (10 MB);
use `+RTS -M<size>' to increase it.

【讨论】:

  • 我刚刚在~/.bashrc 中创建了一个别名alias ghci='ghci +RTS -M500m -RTS',现在一切都很好。非常感谢。
  • 我假设您也可以使用您的.ghci 文件? haskell.org/ghc/docs/7.2.1/html/users_guide/ghci-dot-files.html
  • 其实这个在达到限制的时候并没有中止,所以不是解决办法。此外,ghci 仍然使用比规定更多的内存。例如,我有 4Gb 的 RAM,我将其设置为 -M100m。它告诉我它设置为100Mb,这完全没问题,但是当我运行fib 100000 时,程序仍然几乎冻结了我的机器。它并没有像以前那样完全冻结它,但内存几乎已满,swap 正在被填满,导致大量 IO,使系统无法使用两分钟或更长时间。
  • @Zelphir 为我使用 GHCi-8.0.1。可能是一个已修复的错误。您可以使用堆栈安装它,并创建一个别名,例如alias ghci512="stack ghci --ghci-options '+RTS -M512m -RTS'"。如果您将堆栈用于项目,我建议您坚持使用其 ghci,以免在 RAM 中复制库和文件缓存。
  • 需要注意的是,堆大小并不是唯一可以增长的东西。 GHC 允许您控制堆的最大和建议大小、堆栈的大小以及垃圾收集器的分配区域。
【解决方案2】:

在设置了ulimit -m 的shell 下运行它是一种相当简单的方法。如果您想定期运行一些限制,您可以在运行ghci 之前创建一个执行ulimit 的包装脚本。

【讨论】:

  • 这不起作用。我尝试了ulimit -m 102400 之类的东西,但它仍然会消耗内存。
  • @hobbs @FUZxxl 你应该使用ulimit -v,而不是ulimit -m-m 开关限制物理内存,而你需要限制虚拟:物理+交换。我使用 ulimit -v $(( (1024**2)*2 )) (zsh) 和 4 GiB RAM + 5 GiB 交换,它不会冻结系统。这将内存量限制为 2 GiB,可以放入 ~/.zshrc~/.bashrc
  • 谢谢。我发现这不太有用,因为之后我无法再次更改 shell 中的值。 (只有下来...)
  • @FUZxxl 为什么你不能?我对此没有任何问题(或者您的意思是您不能从 GHCi 更改它?)。它可能不太有用,因为当进程耗尽内存时,它可能会捕获 SEGV 并崩溃,但 GHCi 正在正常处理此问题。 zsh 中有一些相关的有用功能:如果某些正在修改 tty 设置的应用程序(例如,vim)崩溃,您将在屏幕上弄得一团糟,并且某些键不起作用。 Zsh 内置 ttyctl 和参数 -f 将阻止这种情况。
  • 我的意思是这样的:首先,我执行ulimit -v 102400 之类的操作,然后 - 在 ghci 之后 - 我想撤消:ulimit -v unlimited,但出现权限错误。
猜你喜欢
  • 1970-01-01
  • 2021-06-18
  • 2011-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多