
#15503: interpreter: sequence_ (replicate 100000000 (return ())) gobbles up memory -------------------------------------+------------------------------------- Reporter: int-e | Owner: osa1 Type: bug | Status: new Priority: high | Milestone: 8.8.1 Component: GHCi | Version: 8.5 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: Runtime | Unknown/Multiple performance bug | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by osa1): This regression was introduced between 7.10 and 8.0, and reproducible with 8.4 and HEAD. I compared `+RTS -s` outputs of 7.10 and 8.4. 7.10: {{{ $ ./ghci +RTS -s GHCi, version 7.10.3: http://www.haskell.org/ghc/ :? for help λ:2> sequence_ (replicate 100000000 (return ())) λ:3> Leaving GHCi. 12,844,310,920 bytes allocated in the heap 26,753,232 bytes copied during GC 7,744,552 bytes maximum residency (6 sample(s)) 138,736 bytes maximum slop 18 MB total memory in use (0 MB lost due to fragmentation) Tot time (elapsed) Avg pause Max pause Gen 0 1806 colls, 0 par 0.155s 0.158s 0.0001s 0.0055s Gen 1 6 colls, 0 par 0.096s 0.126s 0.0211s 0.0415s TASKS: 4 (1 bound, 3 peak workers (3 total), using -N1) SPARKS: 0 (0 converted, 0 overflowed, 0 dud, 0 GC'd, 0 fizzled) INIT time 0.000s ( 0.002s elapsed) MUT time 4.065s ( 6.690s elapsed) GC time 0.251s ( 0.285s elapsed) EXIT time 0.020s ( 0.023s elapsed) Total time 4.365s ( 7.000s elapsed) Alloc rate 3,159,574,299 bytes per MUT second Productivity 94.3% of total user, 58.8% of total elapsed gc_alloc_block_sync: 0 whitehole_spin: 0 gen[0].sync: 0 gen[1].sync: 0 }}} 8.4: {{{ $ ghci +RTS -s GHCi, version 8.4.3: http://www.haskell.org/ghc/ :? for help Loaded GHCi configuration from /home/omer/rcbackup/.ghci λ:1> sequence_ (replicate 100000000 (return ())) λ:2> Leaving GHCi. 12,869,399,120 bytes allocated in the heap 13,233,009,504 bytes copied during GC 4,007,601,416 bytes maximum residency (14 sample(s)) 15,805,176 bytes maximum slop 8652 MB total memory in use (0 MB lost due to fragmentation) Tot time (elapsed) Avg pause Max pause Gen 0 209 colls, 0 par 3.455s 3.486s 0.0167s 0.4864s Gen 1 14 colls, 0 par 7.993s 10.629s 0.7592s 4.4344s TASKS: 4 (1 bound, 3 peak workers (3 total), using -N1) SPARKS: 0 (0 converted, 0 overflowed, 0 dud, 0 GC'd, 0 fizzled) INIT time 0.001s ( 0.001s elapsed) MUT time 4.252s ( 6.710s elapsed) GC time 11.448s ( 14.115s elapsed) EXIT time 0.000s ( 0.005s elapsed) Total time 15.701s ( 20.831s elapsed) Alloc rate 3,026,874,614 bytes per MUT second Productivity 27.1% of total user, 32.2% of total elapsed gc_alloc_block_sync: 0 whitehole_spin: 0 gen[0].sync: 0 gen[1].sync: 0 }}} Observations: - Productivity is 94% vs. 27% - Almost same amount of allocation in GHCs (very minor difference) - 500x max. residency in GHC 8.4 (7,744,552 vs. 4,007,601,416) So I think for some reason GHC 8.4 keeps retains more things which causes more GC cycles and longer pauses. I compared the byte codes generated by both versions and they're identical so I suspect this is either a problem with the interpreter code or some library function. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15503#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler