Kr0*_*r0e 4 networking garbage-collection haskell memory-leaks lazy-evaluation
我正在玩一些基本的haskell网络的东西,但有一个问题让我疯了.以下非常简单的服务器代码似乎泄漏内存,我只是不知道为什么.
首先,我分叉accept方法,只是回显所有传入的消息.我用Apache Benchmark Tool ab测试了服务器.但经过几次使用ab的测试后,服务器进程开始泄漏内存,但不是很多,而是持续不断.我估计每10000个请求大约1 MB.
问题是:这是某种内部垃圾收集器优化还是确实泄漏内存?我已经测试了程序高达200 MB的内存使用量,仍然在增长.
在这个例子中,我使用严格的ByteStrings.我做的另一个测试是使用基于句柄的IO,这并没有导致内存总共超过3 MB.
使用惰性IO(ByteString.Lazy)导致了同样的问题,但速度更快.我正在使用GHC 7.6(Windows 8).
echoClient :: Socket -> IO ()
echoClient nextSock = do
-- Get a stream of bytes
stream <- NetStrictBS.recv nextSock 120
-- Echo back
NetStrictBS.send nextSock stream
-- Kill the socket
sClose nextSock
acceptClients :: Socket -> IO ()
acceptClients sock = do
-- Start with zero index
loop sock 0
where
loop sock sockId = do
-- Accept socket
(nextSock, addr) <- accept sock
-- Disable Nagle
setSocketOption nextSock NoDelay 1
-- Process client
echoClient nextSock
-- Accept next client
loop sock (sockId + 1)
main = withSocketsDo $ do
-- Setup server socket
sock <- tcpSock
setSocketOption sock ReuseAddr 1
bindSocket sock (SockAddrInet 1337 iNADDR_ANY)
listen sock 128
-- Fork the acceptor
forkIO $ acceptClients sock
print "Server running ... " >> getLine >>= print
Run Code Online (Sandbox Code Playgroud)
我刚跟一位同事说过,他告诉我问题就在这一部分
loop sock (sockId + 1)
Run Code Online (Sandbox Code Playgroud)
我在没有评估的情况下积累了thunk,这肯定会填满堆.我希望这有助于其他人面临类似的问题.