
I have a program, structured approximately like so
main = do let stage1 = e1... let stage2 = e2...stage1... stage3 <- e3...stage2 case something of foo -> output stage1 bar -> output stage2 baz -> output stage3
I think this is an improvement from using multiple main functions, since it reveals the pipeline structure of the program and the modularity of the stages.
It appears¹, however, that naming the result of stage1 prevents it from being garbage collected when subsequent stages are produced. Since stage1 is a huge list, this leads to a space leak.
Hard to tell, but from the code above it looks like stage1 would be retained because it might need to be output after stage3. Could you perhaps move the output of stage1 up the pipeline? If you suspect there's a bug and something is being retained when it shouldn't be, then send us the code and we'll happily investigate.
So, is there any way to avoid this? Do I need to restructure my program? I could conceivably do
main = do let stage1 = e1... let stage2 = e2...(e1...)... :
and so on, but an aggressive (but slightly dumb) compiler might rediscover the similarity and CSE it.
Suggestions more than welcome.
-kzm
¹ Memory retainer profiling shows the product being retained by SYSTEM, so I *think* this is the right interpretation.
A SYSTEM retainer is usually the stack. Cheers, Simon