在Go应用程序中查找内存泄漏

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

Finding Memory Leak in Go Application

问题

我有一个简单的程序,它从网络摄像头读取帧,并将它们的指针放入一个goroutine中的通道中。另一部分从通道中读取帧指针,并将它们弹出到另一个队列中。这个队列对它们进行一些额外的处理,当这个额外的处理完成时,会分配一些内存,但显然这些内存从未被垃圾回收。我在试图弄清楚原因时陷入困境:

这个函数在循环中从通道中读取帧:

func (mr *OpenCVMotionRunner) Run() error {
    log.Println("Starting motion detection... ")

    win := opencv.NewWindow("GoOpenCV: VideoPlayer")
    defer win.Destroy()

    test := mr.md.(*CV2FrameDiffMotionDetector)
    for {
        f := mr.imageChan.PopFrame()
        mr.frame = nil
        switch f := f.(type) {
        default:
            return fmt.Errorf("Unknown frame type")
        case *BSFrame:
            mr.frame = f.ToOpenCVFrame()
        case *OpenCVFrame:
            mr.frame = f
        }
        f = nil
        test.SetCurrent(mr.frame)
        delta := test.Delta()
        if delta != nil {
            win.ShowImage(delta)
            opencv.WaitKey(1)
        } else {
            fmt.Println("wtf")
        }
    }

    return nil
}

问题似乎出在这里:

mr.frame = f.ToOpenCVFrame()

这是类型和方法的定义:

// Frame with byte slice image
type BSFrame struct {
    image  []byte
    Time   time.Time
    Width  uint32
    Height uint32
}

func (f *BSFrame) ToOpenCVFrame() *OpenCVFrame {
    img := opencv.DecodeImageMem(f.image)
    return &OpenCVFrame{
        image:  img,
        Time:   f.Time,
        Width:  f.Width,
        Height: f.Height,
    }
}

这是目标类型的定义:

type OpenCVFrame struct {
    image  *opencv.IplImage
    Time   time.Time
    Width  uint32
    Height uint32
}

顺便提一下,PopFrame只是一个别名为通道的类型上的方法:

type BSFrameChan chan *BSFrame

func (fc BSFrameChan) PopFrame() (frame Frame) {
    frame = <-fc
    return
}

希望这些代码足够展示问题。如果需要的话,其余代码可以在这里找到。

英文:

I've got a simple program that reads frames off a webcam and puts pointers to them on a channel in a goroutine. Another portion reads the frame pointers from the channel and pops them onto another queue. This other queue then does some additional processing to them, and when this additional processing is done, a bunch of memory gets allocated that apparently never gets garbage collected. I'm in over my head trying to figure out why:

This function reads the frames off the channel in a loop:

func (mr *OpenCVMotionRunner) Run() error {
log.Println(&quot;Starting motion detection... &quot;)

// inMotion := false
win := opencv.NewWindow(&quot;GoOpenCV: VideoPlayer&quot;)
defer win.Destroy()

test := mr.md.(*CV2FrameDiffMotionDetector)
for {
	f := mr.imageChan.PopFrame()
	mr.frame = nil
	switch f := f.(type) {
	default:
		return fmt.Errorf(&quot;Unknown frame type&quot;)
	case *BSFrame:
		mr.frame = f.ToOpenCVFrame()
	case *OpenCVFrame:
		mr.frame = f
	}
	f = nil
	test.SetCurrent(mr.frame)
	delta := test.Delta()
	// win.ShowImage(mr.frame.image)
	if delta != nil {
		win.ShowImage(delta)
		opencv.WaitKey(1)
	} else {
		fmt.Println(&quot;wtf&quot;)
	}
}

return nil

}

It appears that the problematic part is this specifically:

mr.frame = f.ToOpenCVFrame()

This is the type and the method:

// Frame with byte slice image
type BSFrame struct {
	image  []byte
	Time   time.Time
	Width  uint32
	Height uint32
}

func (f *BSFrame) ToOpenCVFrame() *OpenCVFrame {
	img := opencv.DecodeImageMem(f.image)
	return &amp;OpenCVFrame{
		image:  img,
		Time:   f.Time,
		Width:  f.Width,
		Height: f.Height,
	}
}

This is the destination type:

type OpenCVFrame struct {
	image  *opencv.IplImage
	Time   time.Time
	Width  uint32
	Height uint32
}

PopFrame, FYI, is just a method on an type that aliases a channel:

type BSFrameChan chan *BSFrame

func (fc BSFrameChan) PopFrame() (frame Frame) {
	frame = &lt;-fc
	return
}

Hopefully this is enough code for the problem to present itself. The rest is here if needed.

答案1

得分: 0

我正在使用的go-opencv库提供了一个Release方法,用于在使用完图像后释放内存。这可以解决这个问题。

英文:

The go library I'm using for the OpenCV bindings provides a Release method on images to deallocate memory when done with an image. This fixes the problem.

huangapple
  • 本文由 发表于 2017年3月14日 14:34:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/42779200.html
匿名

发表评论

匿名网友

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

确定