console.log while debugging leak

console.log is very handy while debugging, using console.log improves productivity while development by many folds. But at times while debugging (especially for memory leak) it may cause side effects which may be confusing. Here is one of the examples.

Once while debugging memory leak in a project of 1000s of line of Javascript code. It was observed in “heap memory profile comparison view” that  one of the objects were showing increase in count. That object was being accessed and modified in a loop, and hence for better view of it and debugging of code added a “console.log(myObject);” Result became even more confusing.

here is a simple test that was performed to verify if console.log adds up to heap snapshots.

Step1 Created a simple markup with 4 objects (small, medium, large and largest)

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <script>
        var small, medium, larget, largest;
        small = {
            a : 1,
            b : 2
        };

        medium = {
            small : small,
            arr   : [1,2,3,4,5],
            str   : "my test"
        };

        large = {
            mediums : {
                medium  : medium,
                medium2 : medium
            },
            small  : small,
            arr    : [medium,medium,medium]
        };

        largest = {
            large_arr : [large,large,large],
            more      : large,
            name      : "largest",
            fewmore   : {
                supa : [{large : large, medium : medium, small : small}, large, small],
                empty : [],
                o     : window
            }
        };

    </script>
</head>
<body>
<button id="small" onclick="console.log(small);">Log Small</button>
<button id="medium" onclick="console.log(medium);">Log Medium</button>
<button id="large" onclick="console.log(large);">Log Large</button>
<button id="largest" onclick="console.log(largest);">Log Largest</button>
</body>
</html>

Step 2 – collected heap snap shot. without clicking any of the buttons.

Result – 2.4MB initial Snapshot

Step 3 – Clicked on “Log Small” button. on click of it just performs a console.log of small object.

Result – 2.5 MB 0.1 MB increase by logging small object. (still OK. If it does not allocate extra memory going forward, while debugging we can assume/consider 0.1 – 0.2 MB increase because of debug logs if it remains constant.)

Step 4 - Clicked on “Log medium” button. on click of it just performs a console.log of medium object.

Result – It remained constant (2.5 MB) even after printing the medium size object.

Step 5 - Clicked on “Log large” button. on click of it just performs a console.log of large object.

Result – Still constant (2.5 MB) .

Step 6 - Clicked on “Log Largest” button. on click of it just performs a console.log of largest object.

Result – Still constant (2.5 MB). awesome does it mean whatever object we log chrome allocates a constant space?

To verify it by expanding object (if expanding object creates any overhead) switched tab to  console tab.

Step 6 -Clicked on console tab and expanded largest object.

After expanding the largest object, profiled again.

Step 7 -Took one more heap snapshot

Result – Heap snapshot increased to 3.3 MB.

Conclusion

console log is very useful for debugging while developing feature, but may be confusing while debugging memory leak. It will be even more confusing if you assume or believe console log must not be getting added to heap snapshot. Chromes new feature “Record Heap Allocations” is useful and helps by associating a number with each object to denote if the object is referenced or copied.

 

 

4 thoughts on “console.log while debugging leak

  1. So, if the application contains a lot of console log statements, it is better to first overwrite the console methods to empty implementations before doing any kind of memory profiling. This would ensure that any accidental interaction with the console log output does not affect the memory heap. Something like,
    window.console = {
    log:function(){},
    info:function(){},
    error:function(){}
    }

  2. Very informative.
    This again touches upon the reach-ability of the object that prevents the Garbage Collector from freeing up the objects. The Console is holding a reference – though it is implied in the article, it is better to be explicit.
    The alternative to still keep Console.log() without holding memory would be to stringify the object during logging – but yes, it may add to the performance, if you are debugging performance issues :-)

    • Thanks Nishanth for reading. Logging stringifyed object, simple string also holds memory. Just try a simple test for(var i=0;i< 10000; ++i) console.log(‘test’+i); and profile, you will find increase in memory.

      I agree to being more clear on Console holds a reference and hence it does not get collected. I will edit and add it to conclusion. Thanks for the recommendation.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

CvyWf

Please type the text above:

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>