#698: GHC's internal memory allocator never releases memory back to the OS
---------------------------------+------------------------------------------
    Reporter:  guest             |        Owner:  igloo           
        Type:  bug               |       Status:  new             
    Priority:  low               |    Milestone:  6.12 branch     
   Component:  Runtime System    |      Version:  6.4.1           
    Severity:  normal            |   Resolution:                  
    Keywords:                    |   Difficulty:  Moderate (1 day)
    Testcase:  N/A               |           Os:  Unknown/Multiple
Architecture:  Unknown/Multiple  |  
---------------------------------+------------------------------------------
Comment (by simonmar):

 Replying to [comment:17 crutcher]:
 > I want to work on this.
 >
 > It seems that there's little agreement on what the 'right' behavior is,
 because there are many different execution models for which different
 behaviors are preferable. It seems we need a means of setting a memory
 reclamation policy, and plugging in some number of implementations of that
 policy, with flags to set it.
 >
 > Off the top of my head, I see a few obvious ones:
 >    * Never return free memory (the current behavior)
 >    * Immediately return free memory (the notional behavior)
 >    * Return outstanding free memory on 'flush' events (nice for the dll
 case?)
 >    * Fixed Buffer - return free memory over X, for some buffer size X.
 >    * Ratio Buffer - return free memory over R, for some ratio of used
 memory.
 >
 > And there's this one, which I'd like to be able to play with, but has
 numerous knobs.
 >    * Derivative Ratio Buffer - at time t, estimate the derivative D(t)
 of memory use, and return free memory over R*D(t+h) for some ration R and
 time step h.

 Bear in mind that the actual memory requirements fluctuate over time due
 to GC activity.  When the copying GC is being used, at a major GC we
 require F*L0+L1 memory, where L0 is the amount of live data at the last
 GC, L1 is the current live data, and F is the value set by `+RTS -F`
 (default 2).  In practice we'll need a little bit more than this, because
 we GC the cycle after the limit has been reached.

 So I suggest that after a major GC we

  * estimate the amount of memory required at the next GC, assuming live
 data
    remains constant, call this M, and add a constant C

  * release any whole megablocks over this limit

 Provide a way to set C, and/or define it as a fraction of M.  I imagine
 that C == M would be a reasonable default: keep double the current
 requirements around just in case.  People who want to be frugal with
 memory could set C == M/3.  Programs with wildly varying memory
 requirements will suffer a performance hit if C is too low.

 Memory could be released between GCs, but the live data value can only be
 calculated at a major GC, so it makes most sense to release memory at a
 major GC.  Programs compiled with `-threaded` get an automatic major GC
 when they're idle (idle time set by `+RTS -I`), programs compiled without
 `-threaded` will have to call `System.Mem.performGC` to release memory if
 they intend to go idle.

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/698#comment:22>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to