[GHC] #15503: interpreter: sequence_ (replicate 100000000 (return ())) gobbles up memory
GHC
ghc-devs at haskell.org
Mon Sep 3 15:49:05 UTC 2018
#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
More information about the ghc-tickets
mailing list