服务器程序与许多客户端保持长时间运行的TCP连接。每个客户端连接由使用forkIO
创建的线程提供。服务器在运行时占用大量内存,因此我自然地进行了分析以寻找可能的空间泄漏。但是,对于大约10k个客户端(因此有10k个线程),结果显示堆的主要部分实际上是由线程分配的STACK。如果我理解正确,这并不奇怪,因为一个线程的堆栈默认以1k开始,并且增加了32k块。由于这些是长期运行的线程,因此这些内存不会被GCed。
我的问题: STACK占用太多空间,有没有办法减少它?
我对此有一些想法:以前我可以使用来自GHC的事件通知API来编写程序而不使用线程,但是由于GHC已经停止导出一些事件处理函数,例如loop
。另一方面,这种变化意味着并发模型(线程与事件)的重大转变,这是非常不受欢迎的,因为Haskell线程非常令人愉快。我想到的另一种方法是拆分/重写线程,以便一个线程完成所有握手+身份验证,创建一个新线程然后退出。新线程将保持循环,希望不需要更多的STACK空间。但是,我不确定这个想法是否正确或可行。