gocv
gocv copied to clipboard
Memory leak with GoCV
Hi guys, I am stuck with the memory leak in my existing code. I spent several days finding the issue and finally decided to write a simple test code to check - maybe the issue with GoCV. After running I saw that I have a memory leak using GoCV. Even though I have closed mats I see memory consumption. Any ideas on how to fix it or maybe I do something wrong?
Steps to Reproduce
package main
import (
"context"
"errors"
"fmt"
"gocv.io/x/gocv"
"log"
"net/http"
"runtime"
"sync"
"time"
)
func main() {
const testURL = "http://xxx.xxx.xxx.xxx/any stream type "
const initialSleep = 30 * time.Second
const concurrency = 10
const runDuration = 10 * time.Second
println("Server started")
go func() {
log.Println(http.ListenAndServe("localhost:6060", nil))
}()
// runtime debug
go func() {
for {
time.Sleep(5 * time.Second)
fmt.Printf(
"num_routines: %d, num_opened_mats: %d\n",
runtime.NumGoroutine(),
gocv.MatProfile.Count(),
)
}
}()
println("Initial sleep - go check memory usage before cameras started")
time.Sleep(initialSleep)
println("Starting cameras...")
ctx, cancelFunc := context.WithTimeout(context.Background(), runDuration)
defer cancelFunc()
wg := &sync.WaitGroup{}
for n := 0; n < concurrency; n++ {
wg.Add(1)
go func() {
err := run(ctx, wg, testURL)
if err != nil {
println("ERROR: ", err.Error())
}
}()
}
wg.Wait()
println("--------------")
println("--------------")
println("All camera routines finished, but the server is still running. You can check RAM again")
<-make(chan bool) // do not stop the server
}
func run(ctx context.Context, wg *sync.WaitGroup, url string) error {
defer wg.Done()
webcam, err := gocv.VideoCaptureFile(url)
if err != nil {
return err
}
defer func() {
if err := webcam.Close(); err != nil {
panic("Failed to close stream: " + err.Error())
}
}()
webcam.Set(gocv.VideoCaptureBufferSize, 2)
img := gocv.NewMat()
defer func() {
if err := img.Close(); err != nil {
panic("Failed to close Mat: " + err.Error())
}
}()
if ok := webcam.Read(&img); !ok {
return errors.New("failed to perform initial read")
}
for i := 0; ; i++ {
if ctx.Err() != nil {
println("time's over, quiting")
break
}
if i%100 == 0 {
fmt.Printf(".") // just show the process is alive
}
if ok := webcam.Read(&img); !ok {
fmt.Sprintln("failed to read frame")
time.Sleep(1 * time.Second)
continue
}
if img.Empty() {
panic("empty image")
}
}
fmt.Println("Finished run")
return nil
}
- Run the code with -tags matprofile build options
- Operating System and version: MacOS/Linux
- OpenCV version used: 4.6
- How did you install OpenCV? the standard way
- GoCV version used: latest
- Go version: 1.19