Skip to content

Space leak in program using lazy bytestrings when compiled with ghc-9.2

Summary

The following program writes a lazy bytestring to a file. It should use very little memory and it does when compiled with ghc-8.10 or ghc-9.0, but when compiled with ghc-9.2, the entire bytestring seems to be retained.

Glancing at differences between the produced core, it looks like ghc-9.2 floats out the bytestring and this is why it is being retained.

Steps to reproduce

Compile the following program with ghc-9.2:

module Main where

import Data.ByteString.Char8 (pack)
import Data.ByteString.Builder

import qualified Data.ByteString.Lazy as L

main =
  L.writeFile "out" 
  . toLazyByteString . foldMap byteString 
  . replicate 1000000000 $ pack "text"

And try to run it with

./Main +RTS -M500M -RTS

It will exhaust the heap

Expected behavior

It should run successfully and use very little memory. Running a version compiled with ghc-8.10.4 with the -t flag tells us that the maximum memory usage was 2M.

Environment

  • GHC version used:
The Glorious Glasgow Haskell Compilation System, version 9.2.0.20210705

Optional:

  • Operating System: Linux
  • System Architecture: x86_64
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information