English 中文(简体)
在哈斯凯尔程序中使用所有可用的内存吗?
原标题:Making use of all available RAM in a Haskell program?

我有8GB的内存, 但哈斯凯尔程序似乎只能使用1.3GB。

我使用这个简单的程序来确定一个GHC程序可以分配多少内存:

import System.Environment
import Data.Set as Set

main = do
         args <- getArgs
         let n = (read $ args !! 0) :: Int
             s = Set.fromList [0..n]
         do
           putStrLn $ "min: " ++ (show $ findMin s)
           putStrLn $ "max: " ++ (show $ findMax s)

这里我发现:

  • running ./mem.exe 40000000 +RTS -s succeeds and reports 1113 MB total memory in use
  • running ./mem.exe 42000000 +RTS -s fails with out of memory error
  • running ./mem.exe 42000000 +RTS -s -M4G errors out with -M4G: size outside allowed range
  • running ./mem.exe 42000000 +RTS -s -M3.9G fails with out of memory error

通过 Windows 任务管理器监测程序表明,最大内存使用量约为1.2GB。

我的系统: Win7, 8 GB RAM, 哈斯凯尔平台 2011.04.0.0, gc 7.0.4。

ghc -O2 mem.hs -rtsopts 合编

我该如何利用我所有可用的记录和档案管理?

最佳回答

目前,在Windows上,GHC是32比特的GHC——我想在7.6到来时,应该有64比特的窗口GHC。

其后果之一是,在 Windows 上,您无法使用超过 4G - 1BLOCK 的内存,因为大小参数允许的最大值为 HS_WORD_MAX :

decodeSize(rts_argv[arg], 2, BLOCK_SIZE, HS_WORD_MAX) / BLOCK_SIZE;

有32位字, HS_WORD_MAX = 232-1

这就是为什么

运行./mem.exe 42000000 +RTS -s -M4G 错误与 -M4G: 超出允许范围的大小

decodeSize () decodesesion () 4G 改为 232

这一限制在提升你的GHC后也将保持不变,直到最终释放出用于Windows的64位GHC。

作为32比特程序,用户模式虚拟地址空间限为2或4GB(取决于 IMAGE_FILE_LARGE_ADIDES_AWARE 旗的状况),参考 Windows 释放的记忆限制

现在,您正在试图构建一个 set , 包含4 200万个4字节 < Int >。 一个 Data.Set.Set 每个元素有五个管理方字( 构件、 大小、 左和右下树下指针、 指针到元素), 因此, et < /code > 将占用约0. 94 GiB 的内存( 1.008 公吨 GB) 。 但这一过程使用大约两倍或更多( 它需要收集垃圾的空间, 至少是活堆的大小 ) 。

在我的 64 位/ 位 Linux 上运行程序, 输入 21000000 输入( 弥补两倍大的 < code> Int 和指针), 我得到

$ ./mem +RTS -s -RTS 21000000
min: 0
max: 21000000
  31,330,814,200 bytes allocated in the heap
   4,708,535,032 bytes copied during GC
   1,157,426,280 bytes maximum residency (12 sample(s))
      13,669,312 bytes maximum slop
            2261 MB total memory in use (0 MB lost due to fragmentation)

                                    Tot time (elapsed)  Avg pause  Max pause
  Gen  0     59971 colls,     0 par    2.73s    2.73s     0.0000s    0.0003s
  Gen  1        12 colls,     0 par    3.31s   10.38s     0.8654s    8.8131s

  INIT    time    0.00s  (  0.00s elapsed)
  MUT     time   12.12s  ( 13.33s elapsed)
  GC      time    6.03s  ( 13.12s elapsed)
  EXIT    time    0.00s  (  0.00s elapsed)
  Total   time   18.15s  ( 26.45s elapsed)

  %GC     time      33.2%  (49.6% elapsed)

  Alloc rate    2,584,429,494 bytes per MUT second

  Productivity  66.8% of total user, 45.8% of total elapsed

top 仅报告内存使用的 >>top < codeg - top - - - - - - - - - top - - - - 可能的任务管理器只报告实时堆积。

似乎 IMAGE_FILE_LARGE_ADERES_AWARE 尚未设定,您的程序仅限于2GB的地址空间,4 200万个 Set 需要的超出此范围,除非您指定一个最大或建议的大小较小:

$ ./mem +RTS -s -M1800M -RTS 21000000
min: 0
max: 21000000
  31,330,814,200 bytes allocated in the heap
   3,551,201,872 bytes copied during GC
   1,157,426,280 bytes maximum residency (12 sample(s))
      13,669,312 bytes maximum slop
            1154 MB total memory in use (0 MB lost due to fragmentation)

                                    Tot time (elapsed)  Avg pause  Max pause
  Gen  0     59971 colls,     0 par    2.70s    2.70s     0.0000s    0.0002s
  Gen  1        12 colls,     0 par    4.23s    4.85s     0.4043s    3.3144s

  INIT    time    0.00s  (  0.00s elapsed)
  MUT     time   11.99s  ( 12.00s elapsed)
  GC      time    6.93s  (  7.55s elapsed)
  EXIT    time    0.00s  (  0.00s elapsed)
  Total   time   18.93s  ( 19.56s elapsed)

  %GC     time      36.6%  (38.6% elapsed)

  Alloc rate    2,611,793,025 bytes per MUT second

  Productivity  63.4% of total user, 61.3% of total elapsed

设定低于其自然使用值的最大堆积大小, 实际让其与 set 所需的空间相比, 价格略长一点的GC时间, 并且建议一个 - H1800M 的堆积大小, 让它只用完成

1831 MB total memory in use (0 MB lost due to fragmentation)

因此,如果您指定了低于2GB(但大到足以适合 Set )的最大堆积大小,应该有效。

问题回答

< a href=> "http://hackage.haskell.org/trac/ghc/ghc/ticket/923" rel="nofollow" > 默认堆积大小是无限的 。

在64位 Windows XP 机器上使用 GHC 7.2, 我可以分配更高的值,

$ ./A 42000000  +RTS -s -H1.6G
min: 0
max: 42000000
  32,590,763,756 bytes allocated in the heap
   3,347,044,008 bytes copied during GC
     714,186,476 bytes maximum residency (4 sample(s))
       3,285,676 bytes maximum slop
            1651 MB total memory in use (0 MB lost due to fragmentation)

$ ./A 42000000  +RTS -s -H1.7G
min: 0
max: 42000000
  32,590,763,756 bytes allocated in the heap
   3,399,477,240 bytes copied during GC
     757,603,572 bytes maximum residency (4 sample(s))
       3,281,580 bytes maximum slop
            1754 MB total memory in use (0 MB lost due to fragmentation)

偶数 :

$ ./A 42000000  +RTS -s -H1.85G
min: 0
max: 42000000
  32,590,763,784 bytes allocated in the heap
   3,492,115,128 bytes copied during GC
     821,240,344 bytes maximum residency (4 sample(s))
       3,285,676 bytes maximum slop
            1909 MB total memory in use (0 MB lost due to fragmentation)

That is, I can allocate up to the Windows XP 2G process limit. I imagine on Win 7 you won t have such a low limit -- this table suggests either 4G or 192G -- just ask for as much as you need (和 use a more recent GHC).





相关问题
Why running a service as Local System is bad on windows?

I am trying to find out the difference between difference service account types. I tumbled upon this question. The answer was because it has powerful access to local resources, and Network Service ...

Programmatically detect Windows cluster configuration?

Does anyone know how to programatically detect that a Windows server is part of a cluster? Further, is it possible to detect that the server is the active or passive node? [Edit] And detect it from ...

get file icon for Outlook appointment (.msg)

I ve read Get File Icon used by Shell and the other similar posts - and already use SHFileInfo to get the associated icon for any given extension, and that works great. However, Outlook uses ".msg" ...

Identifying idle state on a windows machine

I know about the GetLastInputInfo method but that would only give me the duration since last user input - keyboard or mouse. If a user input was last received 10 minutes ago, that wouldn t mean the ...

Terminating a thread gracefully not using TerminateThread()

My application creates a thread and that runs in the background all the time. I can only terminate the thread manually, not from within the thread callback function. At the moment I am using ...