我可以在 Haskell 中限制每个 function/monad/thread 的内存使用量吗?

May I limit memory usage per function/monad/thread in Haskell?

我正在从事一个旨在作为服务工作的研究编译器项目。其中一项要求是某些用户在处理其调用时可能会使用有限的内存(例如,"calls from IP a.b.c.d may use up to 30mb of heap memory")。

我的原型实现是用 C 语言编写的,它简单地使用了一个内存池而不是直接 malloc'ing(由于有效的类型,这实际上很难做到正确)。不过手动内存管理。

在 Haskell 中有什么方法可以通过限制函数、monad 或轻量级线程上的堆使用来实现这一点? (我会接受可能允许我这样做的其他功能语言的建议。)

在最新版本的 GHC 中,可以使用 GHC.Conc 中的 setAllocationCounterenableAllocationLimit 设置 per-thread 分配计数器和限制。当设置限制并且计数器达到 0 时,线程接收到异步异常。

计数器测量分配,而不是实时集的大小。例如,这段代码达到了极限,尽管它的活动集永远不会变得很大:

{-# LANGUAGE NumDecimals #-}
module Main where

import Data.Foldable (for_)
import System.IO
import GHC.Conc (setAllocationCounter,enableAllocationLimit)

main :: IO ()
main = 
  do setAllocationCounter 2e9
     enableAllocationLimit
     let writeToHandle h =
            for_ ([1..]::[Integer])
                 (hPutStrLn h . show)
     withFile "/dev/null" WriteMode writeToHandle
     return ()

分配作为一种衡量标准有点粗糙,但它仍然可以用于检测某些 "out of control" 计算。

Simon Marlow 的

This blog post 进行了更详细的介绍。