networking - Haskell 套接字编程 - 内存泄漏

标签 networking haskell memory-leaks garbage-collection lazy-evaluation

我正在玩一些基本的 Haskell 网络东西,但有一个问题
这让我发疯。以下相当简单的服务器代码似乎泄漏
内存,我只是不知道为什么。

首先,我 fork 接受方法并只回显所有传入的消息。我测试过
使用 Apache Benchmark Tool ab 的服务器。但是在使用 ab 服务器进行了几次测试之后
进程开始泄漏内存,不是很多,而是不断。我猜大约每个 1 MB
10000 个请求。

问题是:这是某种内部垃圾收集器优化还是确实如此
泄漏内存?我已经测试了高达 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

最佳答案

我刚刚和一位同事谈过,他告诉我问题出在这一部分

loop sock (sockId + 1)

我在没有评估的情况下积累了 thunk,这肯定填满了堆。
我希望这可以帮助其他面临类似问题的人。

关于networking - Haskell 套接字编程 - 内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17166495/

相关文章:

linux - 为主机系统无法访问的docker中的两台机器创建网络

java - 为什么我的服务器和客户端在服务器 Activity 开始时断开连接?

haskell - 是否可以使用 Ghcjs、Haste、Elm 等在服务器端渲染 Haskell 前端?

arrays - 如何从一维数组中创建一个二维未装箱数组?

haskell - 为什么 ($ 3) 有签名 (a -> b) -> b?

C++。如何在 Linux 中跟踪 .so 模块的内存分配

Java - 关闭套接字会产生不同的结果

c - TCP 连接 - 延迟 close() 和 RST

c++ - 链接列表程序在收到用户的值后崩溃

iphone - 我必须在下面的代码中释放 NSDate 吗?