2017-02-20 18 views
9

我正在研究一個旨在作爲服務工作的研究編譯器項目。其中一個要求是某些用戶在處理其呼叫時可能有限的內存使用情況(例如,「來自IP a.b.c.d的呼叫可能使用多達30mb的堆內存」)。我的原型實現,用C語言編寫,直接使用了一個內存池indeire(直接由於有效的類型實際上很難得到)。手動內存管理,但。我可以限制Haskell中每個函數/ monad /線程的內存使用情況嗎?

有沒有什麼辦法在Haskell中實現這一點,通過限制函數,monad或輕量級線程上的堆使用? (我會接受其他功能的語言可能讓我做這件事的建議。)

+0

你究竟想限制什麼?爲任意Haskell代碼限制任意內存可能不會成爲可能,但您可以通過將其隱藏在類型類後面來限制對某些特定資源的訪問。 – Cirdec

+7

操作系統進程可能具有有限的內存。一個可能的解決方案是在新進程中分叉一個新進程和['setResourceLimit'](https://hackage.haskell.org/package/unix-2.7.2.1/docs/System-Posix-Resource.html),並且用[Remote](https://hackage.haskell.org/package/remote-0.1.1/docs/Remote.html)等方式與它進行交流。你需要限制在新進程中運行的代碼不如'IO()'強大。 – Cirdec

+0

是的,我試圖限制整個編譯過程的內存使用情況。這些可能非常昂貴,如果我不以某種方式限制堆的使用,我會很容易受到DoS的攻擊。 – paulotorrens

回答

10

在GHC的最新版本,它可以設置每個線程分配櫃檯和限制,使用setAllocationCounterenableAllocationLimitGHC.Conc。當限制被設置並且計數器達到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() 

分配是有點粗糙的措施,但它仍然是有用的來檢測一些「失控」的計算。

This blog post通過Simon Marlow進行更多細節。

+0

足夠接近。謝謝。 – paulotorrens

相關問題