[GHC] #12889: memory leak

GHC ghc-devs at haskell.org
Mon Nov 28 17:51:08 UTC 2016


#12889: memory leak
-------------------------------------+-------------------------------------
        Reporter:  zoranbosnjak      |                Owner:
            Type:  bug               |               Status:  closed
        Priority:  normal            |            Milestone:
       Component:  Compiler          |              Version:  8.0.1
      Resolution:  invalid           |             Keywords:
Operating System:  Unknown/Multiple  |         Architecture:
                                     |  Unknown/Multiple
 Type of failure:  None/Unknown      |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------
Changes (by rwbarton):

 * status:  new => closed
 * resolution:   => invalid


Comment:

 Your program is retaining the evaluated list `[1,2,3,...]` which grows
 forever. You might say this is dumb, and in this case it is. But, if you
 had written
 {{{#!hs
 task = forM_ (filter expensiveTest [(1::Integer)..10000000]) $ \cnt -> do
 ...
 }}}
 then you might well have filed a bug wondering why your program is
 recalculating the list `filter expensiveTest [(1::Integer)..10000000]` for
 every call to `task`, whenever you make any of your changes 1, 2, 3. So,
 there is a real tension here.

 The normal behavior is to calculate a given expression once per time that
 its surrounding function is entered. Here there is no function around
 `[(1::Integer)..]` at all, so we calculate it just once during the
 lifetime of the program. If you remove the recursive call to `main` then
 the value is also used just once, so it can be GCed as it is generated,
 but normally this will lead to a space leak.

 The reason that the other changes cause `task` to be recalculated are more
 obscure, and probably not very interesting. If you want to tell GHC to
 always recalculate `task`, it's better to introduce an explicit function,
 like

 {{{#!hs
 task :: () -> ReaderT () IO ()
 task () = forM_ [(1::Integer)..] $ \cnt -> do ...
 }}}

 (Even then GHC might decide to share the computation of
 `[(1::Integer)..]`, but then you have a different issue.)

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/12889#comment:1>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list