What makes GHC's GC good for purely functional workloads?
Simon Marlow
marlowsd at gmail.com
Wed Nov 23 11:31:22 CET 2011
On 23/11/2011 04:09, Edward Z. Yang wrote:
> Apologies if this has been asked before. In some ways
> GHC's garbage collectors are very traditional, so I was
> wondering what magic dust makes it do better in Haskelly
> workloads (e.g. whereas you'd need to do a bit more work
> in the JVM to make some allocation pattern play nice.)
Our GC is generally tuned towards making allocation fast. So we use
bump-pointer allocation and allocate several objects at once, and we use
generational GC where the default nursery size is small (about L2
cache-sized). Young-generation collections are very quick - on the
order of 10us. So we collect a lot of the garbage before it even hits
main memory; this is also what makes GHC's GC scale reasonably well for
parallel programs.
On the other hand, our write barriers are more expensive than you'd
typically find in a JVM, but they are more accurate: remembered set
rather than card marking. This is a good tradeoff because mutation is
rare in Haskell. The one exception is thunk update - there might be
room for experimenting with a cheaper write barrier there.
One thing I'm particularly proud of in our GC is the block layer. All
memory is managed in units of blocks (currently 4k, but that's just a
constant you can change). It makes everything a lot simpler, including
parallel GC. We have a paper about it:
http://community.haskell.org/~simonmar/papers/parallel-gc.pdf
Cheers,
Simon
More information about the Glasgow-haskell-users
mailing list