计时器开销导致内存溢出

huangapple go评论73阅读模式
英文:

Timer overhead causing memory overflow

问题

从timer.Stop() 文档中可以得知:

Stop方法可以阻止定时器触发。如果调用成功停止了定时器,返回true;如果定时器已经过期或已经停止,返回false。Stop方法不会关闭通道,以防止错误地从通道中读取。

我需要找到一种方法来销毁程序中通过AfterNewTimer创建的定时器对象或通道。我并没有直接使用这些函数,而是使用另一个实现了超时功能的库。处理越多的请求,程序的内存就会不断增加,然后被终止。

我已经查看了以下位置,但没有找到太多帮助:

  1. https://groups.google.com/forum/#!topic/golang-nuts/A597Btr_0P8
  2. https://groups.google.com/forum/#!topic/golang-nuts/-xnFsH_ZRqU
  3. https://groups.google.com/forum/#!topic/golang-nuts/rYthykbCLHk
  4. 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:

  1. https://groups.google.com/forum/#!topic/golang-nuts/A597Btr_0P8
  2. https://groups.google.com/forum/#!topic/golang-nuts/-xnFsH_ZRqU
  3. https://groups.google.com/forum/#!topic/golang-nuts/rYthykbCLHk
  4. 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 &lt;-chan time.Time
if c.timeout &gt; 0 {
	timeoutCh = time.After(c.timeout)
}

select {
case err := &lt;-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 &lt;-timeoutCh:
	close(call.timeout)
	c.handleTimeout()
	return nil, ErrTimeoutNoResponse
case &lt;-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

huangapple
  • 本文由 发表于 2016年2月20日 02:38:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/35512541.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定