[Haskell-cafe] Re: Profiling makes memory leak go away? Is Haskell apractical language?

apfelmus apfelmus at quantentunnel.de
Wed Apr 11 04:34:10 EDT 2007


Claus Reinke wrote:
> i'm just guessing here, but if that is indeed the problem, you would
> need to exert
> more control over what is evaluated when and shared where:
> 
> - evaluate rResult synchronously with rTokens, instead of rResult long
> after
>    rTokens has unfolded the reply
> - evaluate rResult independent of rTokens, on a separate copy of reply

Brandon Michael Moore wrote:
> It's the same problem you see in
> 
> --argument to break sharing
> input () = 'a' : input ()
> 
> main = let text = input() in putStr (text ++ [last text])

Ah, of course. That's what's going on:

>> result = rResult reply -- Lazy; has value when parsing is done
>> extra = case result ... -- Lazy; has value when parsing is done
>> parsed = rTokens reply -- Has some values "immediately"

On evaluating 'parsed', the DList of tokens gets expanded. But by
keeping a reference to 'reply' via 'result', this expanded list has to
be kept in memory! I mean, the definition of 'result' formally specifies
that it depends on the hole 'reply' and the GC may not throw away parts
of it.

This is similar to the described space leaks in

    http://citeseer.ist.psu.edu/sparud93fixing.html


I believe that a single deconstruction of the reply as in

  let tokens = case args of
    ["free"] -> rTokens reply
    ["leak"] -> case reply of
      Reply { rResult = result, rTokens = parsed } ->
         let extra = maybe (D.singleton $ Token {tText='!'})
                           (const D.empty) result
         in D.append parsed extra

is a cure for your space leak.


Regards,
apfelmus



More information about the Haskell-Cafe mailing list