golang读取XML内存泄漏?
Posted
技术标签:
【中文标题】golang读取XML内存泄漏?【英文标题】:golang reading XML memory leak? 【发布时间】:2014-01-30 22:54:24 【问题描述】:我们最近使用 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
的top100
得到以下内容:
(pprof) top100
Total: 56.0 MB
55.0 98.2% 98.2% 55.0 98.2% encoding/xml.copyValue
1.0 1.8% 100.0% 1.0 1.8% cnew
0.0 0.0% 100.0% 0.5 0.9% bytes.(*Buffer).WriteByte
0.0 0.0% 100.0% 0.5 0.9% bytes.(*Buffer).grow
0.0 0.0% 100.0% 0.5 0.9% bytes.makeSlice
0.0 0.0% 100.0% 55.5 99.1% encoding/xml.(*Decoder).Decode
...
稍后运行此程序,在盒子内存不足之前,会产生更高的总数,但百分比几乎相同。任何人都可以帮助我们吗?我们缺少什么?
提前致谢!
【问题讨论】:
我已经多次看到这个奇怪的循环。不知道它来自哪里,但是那里的代码太多了。试试这个:play.golang.org/p/GFkmfn_CYV(也修复了你的内存问题) 谢谢!我以前没见过range ticker
!
【参考方案1】:
尝试每次打印出您的消息。它将继续将字段附加到原始结构上。
你需要用m = message
在你做你需要做的事情后重置消息,清除它,否则它会继续增长。
【讨论】:
伟大的收获!我想知道这是错误还是期望的行为。在我看来像一个错误。 不,这是期望的行为。根据文档:“Unmarshal 通过扩展切片的长度并将元素映射到新创建的值,将 XML 元素映射到切片。”【参考方案2】:我尚未对此进行测试,但您是否尝试在每次执行此操作时将 XML 解组为一个新变量?
据我所知,您是在指针中执行此操作,这可能会导致内存出现一些问题。
当然,我可能完全错了。
【讨论】:
以上是关于golang读取XML内存泄漏?的主要内容,如果未能解决你的问题,请参考以下文章