英文:
Timer overhead causing memory overflow
问题
从timer.Stop() 文档中可以得知:
Stop方法可以阻止定时器触发。如果调用成功停止了定时器,返回true;如果定时器已经过期或已经停止,返回false。Stop方法不会关闭通道,以防止错误地从通道中读取。
我需要找到一种方法来销毁程序中通过After或NewTimer创建的定时器对象或通道。我并没有直接使用这些函数,而是使用另一个实现了超时功能的库。处理越多的请求,程序的内存就会不断增加,然后被终止。
我已经查看了以下位置,但没有找到太多帮助:
- https://groups.google.com/forum/#!topic/golang-nuts/A597Btr_0P8
- https://groups.google.com/forum/#!topic/golang-nuts/-xnFsH_ZRqU
- https://groups.google.com/forum/#!topic/golang-nuts/rYthykbCLHk
- https://groups.google.com/forum/#!topic/golang-nuts/hjioKxSJ3Tc
请帮忙,我迫切需要解决这个问题。
更新:
可疑的代码位于https://github.com/gocql/gocql/blob/986e33a705412161497203d55d0669d04282f5ff/conn.go#L546
var timeoutCh <-chan time.Time
if c.timeout > 0 {
timeoutCh = time.After(c.timeout)
}
select {
case err := <-call.resp:
if err != nil {
if !c.Closed() {
// 如果连接已关闭,则无法释放流,
// 这是因为请求仍未完成,我们从另一个流中获得了另一个错误,
// 导致连接关闭。
c.releaseStream(stream)
}
return nil, err
}
case <-timeoutCh:
close(call.timeout)
c.handleTimeout()
return nil, ErrTimeoutNoResponse
case <-c.quit:
return nil, ErrConnectionClosed
}
我如何知道这个问题?我运行了go tool pprof来捕获memprof,并显示如下:
英文:
From the timer.Stop() documentation
> Stop prevents the Timer from firing. It returns true if the call
> stops the timer, false if the timer has already expired or been
> stopped. Stop does not close the channel, to prevent a read from the
> channel succeeding incorrectly.
I need to find a way to destroy timer object or channel created in program via After or NewTimer. I am not using these functions directly, just another library that implements timeout using these. The more requests I handle the program's memory keeps on increasing and then gets killed.
I have looked into the following places but without much help:
- https://groups.google.com/forum/#!topic/golang-nuts/A597Btr_0P8
- https://groups.google.com/forum/#!topic/golang-nuts/-xnFsH_ZRqU
- https://groups.google.com/forum/#!topic/golang-nuts/rYthykbCLHk
- https://groups.google.com/forum/#!topic/golang-nuts/hjioKxSJ3Tc
Please help, need to fix this desperately.
UPDATE
The suspected code is at https://github.com/gocql/gocql/blob/986e33a705412161497203d55d0669d04282f5ff/conn.go#L546
var timeoutCh <-chan time.Time
if c.timeout > 0 {
timeoutCh = time.After(c.timeout)
}
select {
case err := <-call.resp:
if err != nil {
if !c.Closed() {
// if the connection is closed then we cant release the stream,
// this is because the request is still outstanding and we have
// been handed another error from another stream which caused the
// connection to close.
c.releaseStream(stream)
}
return nil, err
}
case <-timeoutCh:
close(call.timeout)
c.handleTimeout()
return nil, ErrTimeoutNoResponse
case <-c.quit:
return nil, ErrConnectionClosed
}
How do I know this ? I ran go tool pprof to capture memprof and what it showed is :
答案1
得分: 2
我已经合并了一个修复,https://github.com/gocql/gocql/pull/661 如果你遇到进一步的问题,请提出一个问题。
英文:
I've merged a fix for this, https://github.com/gocql/gocql/pull/661 please raise an issue if you run into further issues
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论