question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Memory leaks with detectAllFaces

See original GitHub issue

Hi,

I have this coffeescript code snippet :

# Analyse the new frame
    analyseFrame: (next = _.noop) ->
    
        @testCount = 200 unless (typeof(@testCount) is 'number')
    
        # Skip if not capturing
        return unless Service.isCapturing
    
        # get frame
        _frame = Service.videoCapture.getFrame()
    
        # get frame date
        @currentFrameTime = Date.now()
    
        # clear old faces in history
        @refreshFaceHistory(@currentFrameTime)
    
        #convert frame to a tensor
        try
            _data = new Uint8Array(_frame.cvtColor(cv.COLOR_BGR2RGB).getData().buffer)
            _tensorFrame = tfjs.tensor3d(_data, [_frame.rows, _frame.cols, 3])
        catch _err
            @log.error "Error instantiating tensor !!!"
            @log.error _err.message

        faceapi.detectAllFaces(_tensorFrame, @faceDetectionOptions).then (_detectedFaces) =>
            @log.debug _detectedFaces
        
            # fill face history with detceted faces
            _detectedFaces = @fillFacesHistory(_detectedFaces)
        
            # draw boxes on image
            Service.videoCapture.drawFaceBoxes(_frame, _detectedFaces)
        
            # Get partial time
            Service.frameDuration = Date.now() - @currentFrameTime
        
            # write latency on image
            Service.videoCapture.writeLatency(_frame, Service.frameDuration)
        
            # show image
            Service.faceRecoUtils.showImage(_frame)
        
            # Call next
            _delayNextFrame = Math.max(0, 1000/@options.fps - Service.frameDuration)
        
            # DEBUG MEMORY DUMP every 30 sec  
            if @testCount > (5*30)
        
                @testCount = 0
  
                _dumpPath = path.resolve(__dirname + "./../memoryDump/" + @currentFrameTime + '.heapsnapshot')
                heapdump.writeSnapshot _dumpPath
   
        
        
            setTimeout =>
                # console.log "Next frame : #{_delayNextFrame}ms - TOTAL : #{_frameDuration}ms"
                @analyseFrame()
            , (_delayNextFrame)
        
        
        @testCount++

I feel like detectAllFaces is causing memory leaks. In deed, the corresponding nodejs process gains approximately 0.5 to 1% memory usage for each processed frame ! So my RAM get totally filled really quickly. I tried to get memory dump using heapdump but I don’t see anything anormal (all my dumps have same size on Google Chrome inspector). So this could means that memory leaks come from the C++ size of face-api.js, right ?

At first, I thought the leak could comes from combination of loops and promises or from Service.videoCapture. But I get similar results with the below code. The only difference being that RAM is filled slower. Which seems normal since the image used is smaller than my webcam’s frames.

# Analyse the new frame
    analyseFrame: (next = _.noop) ->

        # Skip if not capturing
        return unless Service.isCapturing

        _currentFunctionCallTime = Date.now()

        # get frame
        _frame = Service.videoCapture.getFrame()

        # if analyzer is ready, we can take a frame from webcam and process it
        if @analyzerIsReady

            @analyzerIsReady = false

            # get frame date
            @currentFrameTime =_currentFunctionCallTime

            # get frame
            _analyzedFrame = _frame

            # clear old faces in history
            @refreshFaceHistory(@currentFrameTime)

            @log.debug "faceHistory.length = ", Service.faceHistory.length

            _analyzedFrame = cv.imread('/home/loophole/eventbots-packages/eb/tiki-service-facedetection/models/bbt3.jpg')

            #convert frame to a tensor
            try
                _data = new Uint8Array(_analyzedFrame.cvtColor(cv.COLOR_BGR2RGB).getData().buffer)
                _tensorFrame = tfjs.tensor3d(_data, [_analyzedFrame.rows, _analyzedFrame.cols, 3])
            catch _err
                @log.error "Error instantiating tensor !!!"
                @log.error _err.message

            faceapi.detectAllFaces(_tensorFrame, @faceDetectionOptions).then (_detectedFaces) =>

                # fill face history with detceted faces
                _detectedFaces = @fillFacesHistory(_detectedFaces)

                # Get partial time
                Service.frameDuration = Date.now() - @currentFrameTime

                # Call next
                _delayNextFrame = Math.max(0, 1000/@options.fps - Service.frameDuration)

                setTimeout =>
                    @analyzerIsReady = true
                , (_delayNextFrame)

        _callDuration = Date.now() - _currentFunctionCallTime

        _delayNextCall = Math.max(0, 1000/@options.callPerSec - _callDuration)

        setTimeout =>
                @analyseFrame()
            , (_delayNextCall)

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:6 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
justadudewhohackscommented, Jan 30, 2019

Hey, there is no C++ side of face-api.js. If you are really experiencing memory leaks, it either comes from tensorflow or opencv4nodejs, which I find very unlikely as well since I didn’t experience any kind of leaks in long running applications using opencv4nodejs + face-api.js with similar code.

One thing that bothers me though, I don’t see you disposing the tensor _tensorFrame, which you create for every frame. If you do not dispose it after your done with it, e.g. _tensorFrame.dispose(), then your application will indeed leak memory. You can also check the tracked memory of tfjs using tf.memory().

0reactions
neumartincommented, Sep 5, 2019

Solved!, only happend when run in debug mode, maybe never dispose because of that. Thanks!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Preventing memory leak with detectAllFaces() ? #345 - GitHub
I am using detectAllFaces() with TinyFaceDetector. Every 500ms I feed it a new image to analyze. I noticed that I'm getting a memory...
Read more >
Avoid memory leaks with promises and loop in coffee-script ...
I am currently trying to perform some operations using promises in a loop but I ended up with huge memory leaks. My problem...
Read more >
MemLab: An open source framework for finding JavaScript ...
We've open-sourced MemLab, a JavaScript memory testing framework that automates memory leak detection. Finding and addressing the root cause ...
Read more >
Node.js Memory Leak Detection: How to Debug & Avoid Them
Learn what Node.js memory leaks are. Discover common causes and go through the whole debugging process, from detection to fixing and ...
Read more >
How to Find, Fix, and Prevent Node.js Memory Leaks
Memory management for any application is essential. This post looks at what memory leaks are and how to avoid them in Node.js applications....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found