我正在尝试开发一个持续运行的程序。
它应该每隔sleepPool
秒从数据库中提取一些数据,并以非阻塞的方式“处理”信息(至少这是我正在尝试做的事情)。
问题是内存不断增长,所以我想知道我是否做错了。
以下是我程序的摘录。
var uCh = make(chan *user, buffLimit) //emits new users to process
var statsCh = make(chan *user, buffLimit) //emits new users to store
func main() {
go emitUser(db)
go consumeUser(db)
for ur := range statsCh {
log.Infoln(ur)
}
}
func emitUser(db *sql.DB) {
for {
time.Sleep(sleepPool * time.Second)
log.Infoln("looking for new users")
rows, err := rowsD.Query()
for rows.Next() {
uCh <- usr
}
}
}
func consumeUser(db *sql.DB) {
for usr := range uCh {
go func(usr *user) {
//do something with the user
statsCh <- usr
}(usr)
}
}
我读过我可能需要关闭通道,以便gc可以回收内存,但我不知道该怎么做(因为程序应该连续运行),如果我真的需要这样做,因为始终读取数据(由main
范围保证),因此我假设内存已被回收。
答案 0 :(得分:3)
你没有足够的时间让GC开始,等待一个小时然后检查内存。
如果你真的想要(糟糕的想法并且会减慢你的程序)强制它释放内存你可以使用类似的东西:
import "runtime/debug"
//........
func forceFree() {
for _ = range time.Tick(30 * time.Second) {
debug.FreeOSMemory()
}
}
func init() {
go forceFree()
}
答案 1 :(得分:0)
这段代码可以做很多无害的传递,但不应泄漏任何东西。
我的猜测是rowsD.Query
方法有某种缓存或其他泄漏。
当然,它可能只是碎片,或垃圾收集器的人工制品(在这种情况下,你应该看到内存使用水平关闭,甚至下降,随着时间的推移)。