我们最近使用golang和encoding/xml
解码了很多XML。我们注意到,在相当多的文件之后,我们的盒子耗尽内存,开始交换,并且通常会死于不幸的死亡。所以我们做了一个测试程序。这是:
package main
import (
"encoding/xml"
"io/ioutil"
"log"
"time"
)
// this XML is for reading AWS SQS messages
type message struct {
Body []string `xml:"ReceiveMessageResult>Message>Body"`
ReceiptHandle []string `xml:"ReceiveMessageResult>Message>ReceiptHandle"`
}
func main() {
var m message
readTicker := time.NewTicker(5 * time.Millisecond)
body, err := ioutil.ReadFile("test.xml")
for {
select {
case <-readTicker.C:
err = xml.Unmarshal(body, &m)
if err != nil {
log.Println(err.Error())
}
}
}
}
它所做的就是一遍又一遍地重复解码XML文件。我们的框显示相同的症状:二进制文件的内存使用量无限制地增长,直到框开始交换。
我们还在一些分析代码中添加了20秒后触发上述脚本的代码,并从pprof
的{{1}}获得了以下内容:
top100
稍后运行此选项,在该框耗尽内存之前,会产生更高的总数但几乎相同的百分比。任何人都可以帮助我们吗?我们缺少什么?
提前致谢!
答案 0 :(得分:7)
每次尝试打印出您的信息。它将继续将字段附加到原始结构上。
您需要在执行完所需操作后使用m = message{}
重置邮件,将其清除,否则邮件会继续增长。
答案 1 :(得分:0)
我还没有测试过这个,但是你每次尝试将XML解组为一个新的变量吗?
据我所知,你是在一个指针中做的,这可能会对内存产生一些问题。
但当然,我可能完全错了。