致命错误内存不足

时间:2014-01-07 13:14:09

标签: go mgo

所以我在go中编写了一个守护程序来处理大约800k文档,并且我遇到了内存不足的问题。

从我从mongodb获取文档时看到的内存使用量随着每个循环而增加。

func main() {
session, err := mgo.Dial("localhost")
if err != nil { panic(err) }
defer session.Close()

subscriptionsC  = session.DB("sm").C("subscriptions")
subscriptions   := []Subscription{}

for {
    subscriptions = GetSubscriptions()

另一个功能是:

func GetSubscriptions()([]Subscription) {
    result  := []Subscription{}
    err    := subscriptionsC.Find(nil).Prefetch(0.0).All(&result)

    if err != nil { Log("signups_err", err.Error() + "\n") }
    return result
}

我不知道它是否在每个循环中重新声明数组或者究竟发生了什么。

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

mgo的作者。

您的代码没有任何问题,但它不完整,因此您可能无法显示的内容实际上是泄漏内存。

你能提供泄漏记忆的完整例子吗?

顺便说一句,缓存/池化会话没有意义,因为mgo会在内部为您处理资源池。您必须做的是确保关闭您创建的会话,示例代码会这样做。

OP下面的评论后更新:

  

似乎问题在于大量的文档。 pastebin.com/jUDmbS4z这将每10-15分钟(大约4-5个循环)崩溃一次。它在一个循环中从mongo获得大约600k文档。

是的,运行同时在内存中加载大量数据的查询很容易因为与mgo无关的多种原因而造成麻烦..内存碎片,非精确收集器等等。只需在项目到达时迭代它们照常;它很舒服,快速,并且会大大减少使用的内存量,正如您已经想到的那样。

答案 1 :(得分:0)

由于调用GetSubscriptions()然后调用循环result := []Subscription{},数组在每个循环中都被定义为inialized,但我认为这不是问题的根源。

问题可能来自您的全局会话,请参阅Database connections in web applications,正确的方法是使用会话池。

修改 :另见How do I call mongoDB CRUD method from handler?