
On Sunday 20 February 2011 16:38:17, tsuraan wrote:
I have a streaming network protocol where each message in the stream is prefixed by a 64-bit message length marker. Lazy ByteStrings seem to be an elegant way to wrap network communications, so I'm using them. I have one concern though: how can I prevent my program from hanging on to the beginning of the stream? My code looks roughly like this:
lazy <- getContents clientSock let (lenBS, rest1) = splitAt 8 lazy let length = runGet getWord64be lenBS let (msg, rest2) = splitAt (fromIntegral length) rest1 -- process msg
The program never uses that initial "lazy" again, but it's there, and it's been assigned, so I assume that reference to the head of the stream will always be around, and thus always consuming memory.
No, that need not be. If the compiler sees that it's never referenced again, it can be garbage collected (assuming the consumption pattern of msg allows that to be garbage collected incrementally). Try out whether your programme has a space leak by giving it a long input. If it has, ask again.
Is there a way to indicate to haskell that I want to "forget" about that assignment, so the runtime doesn't need to keep the stream around? In this case, I think I could do the stream processing in a tail-recursive loop, and thus lose the previous references to the stream, but is there a more specific way to tell haskell that I'm done with some data?
Normally, that shouldn't be necessary. If you're done with some data, it should be garbage collected pretty soon. There are some situations where an unintended and unneeded reference to some data is kept around and prevents it from being collected, but in general, the compilers are rather good at managing memory.