title: Why is my little STRef Int require allocating gigabytes?
body: <pre><code>3,200,056,496 bytes allocated in the heap
  </code></pre>
  
  <p>Wut? This is a small test for STRef:</p>
  
  <pre><code>bigNumber =
      runST $ do
          ref &lt;- newSTRef (0 :: Int)
          replicateM_ 100000000 $ modifySTRef' ref (+1)
          readSTRef ref
  </code></pre>
  
  <p><code>modifySTRef'</code> is strict. <code>STRef</code> is supposed to operate directly on memory so I don't see the need for lots of allocations.</p>
  
  <p>Here's the full code:</p>
  
  <pre><code>import Control.Monad.ST
  import Control.Monad
  import Data.STRef
  
  bigNumber :: Int
  bigNumber =
      runST $ do
          ref &lt;- newSTRef (0 :: Int)
          replicateM_ 100000000 $ modifySTRef' ref (+1)
          readSTRef ref
  
  main :: IO ()
  main = print bigNumber
  </code></pre>
  
  <p>Build for profiling like:</p>
  
  <pre><code>ghc -O2 -rtsopts -prof -auto-all -caf-all -fforce-recomp tryST.hs
  </code></pre>
  
  <p>Run like:</p>
  
  <pre><code>./tryST +RTS -pa -sstderr
  </code></pre>
  
  <p>Highlight from <code>tryST.prof</code></p>
  
  <pre><code> bigNumber    Main  95 1   95.7  100.0    95.7  100.0   1357 1600000032
  </code></pre>
  
  <p>The RTS report:</p>
  
  <pre><code>3,200,056,496 bytes allocated in the heap
        360,624 bytes copied during GC
          46,040 bytes maximum residency (2 sample(s))
          23,592 bytes maximum slop
              1 MB total memory in use (0 MB lost due to fragmentation)
  
                                    Tot time (elapsed)  Avg pause  Max pause
  Gen  0      6102 colls,     0 par    0.03s    0.03s     0.0000s    0.0002s
  Gen  1         2 colls,     0 par    0.00s    0.00s     0.0007s    0.0013s
  
  INIT    time    0.00s  (  0.00s elapsed)
  MUT     time    1.33s  (  1.38s elapsed)
  GC      time    0.03s  (  0.04s elapsed)
  RP      time    0.00s  (  0.00s elapsed)
  PROF    time    0.00s  (  0.00s elapsed)
  EXIT    time    0.00s  (  0.00s elapsed)
  Total   time    1.35s  (  1.42s elapsed)
  
  %GC     time       1.9%  (2.5% elapsed)
  
  Alloc rate    2,413,129,982 bytes per MUT second
  
  Productivity  98.1% of total user, 93.6% of total elapsed
  </code></pre>
  
  <p>This program isn't as fast as I'd like but the productivity is 98%. Great. Maximum residency 46k. Cool. But what is with all that allocation?</p>