Skip to content
This repository has been archived by the owner on Jul 25, 2020. It is now read-only.

IE memory Leak #6

Open
jbadeau opened this issue Mar 5, 2013 · 7 comments
Open

IE memory Leak #6

jbadeau opened this issue Mar 5, 2013 · 7 comments

Comments

@jbadeau
Copy link

jbadeau commented Mar 5, 2013

The line with:

var console = (/** @type {Object} */ global.console);
results in memory leak in IE9-

@dmp42
Copy link
Contributor

dmp42 commented Mar 5, 2013

It's called only once.
Do you mean it's leaking across page reloads?
Also, what tool did you use to detect the leak?

@jbadeau
Copy link
Author

jbadeau commented Mar 6, 2013

Hi,
Sorry for the short explanation, I accidentally pressed comment. This issues happens after a page refresh. I noticed it by using the good old windows process viewer. Seems the console var cannot be dereferenced. I have fixed the issue and will make a pull request.

@beatgammit
Copy link

@jbadeau - Any progress on this?

@jbadeau
Copy link
Author

jbadeau commented May 7, 2013

I am not allowed to do a pullrequest but I can post the changes:

/**

(function(){
"use strict";

/**

  • Returns a function which calls the specified function in the specified
  • scope.
    *
  • @param {Function} func
  •        The function to call.
    
  • @param {Object} scope
  •        The scope to call the function in.
    
  • @param {...*} args
  •        Additional arguments to pass to the bound function.
    
  • @returns {function(...[*]): undefined}
  •        The bound function.
    
    /
    var bind = function(func, scope, args)
    {
    var fixedArgs = Array.prototype.slice.call(arguments, 2);
    return function()
    {
    var args = fixedArgs.concat(Array.prototype.slice.call(arguments, 0));
    (/
    * @type {Function} */ func).apply(scope, args);
    };
    };

// Create console if not present
if (!window["console"]) window.console = /** @type {Console} / ({});
var console = (/
* @type {Object} */ window.console);

// Implement console log if needed
if (!console["log"])
{
// Use log4javascript if present
if (window["log4javascript"])
{
var log = log4javascript.getDefaultLogger();
console.log = bind(log.info, log);
console.debug = bind(log.debug, log);
console.info = bind(log.info, log);
console.warn = bind(log.warn, log);
console.error = bind(log.error, log);
}

// Use empty dummy implementation to ignore logging
else
{
    console.log = (/** @param {...*} args */ function(args) {});
}

}

// Implement other log levels to console.log if missing
if (!console["debug"]) console.debug = console.log;
if (!console["info"]) console.info = console.log;
if (!console["warn"]) console.warn = console.log;
if (!console["error"]) console.error = console.log;

// Wrap the log methods in IE (<=9) because their argument handling is wrong
// This wrapping is also done if the consoleShimTest symbol is set. This
// is needed for unit testing.
if (window["consoleShimTest"] != null ||
eval("/_@cc_on @jscript_version <= 9@/"))
{
/**
* Wraps the call to a real IE logging method. Modifies the arguments so
* parameters which are not represented by a placeholder are properly
* printed with a space character as separator.
*
* @param {...*} args
* The function arguments. First argument is the log function
* to call, the other arguments are the log arguments.
*/
var wrap = function(args)
{
var i, max, match, log;

    // Convert argument list to real array
    args = Array.prototype.slice.call(arguments, 0);

    // First argument is the log method to call
    log = args.shift();

    max = args.length;
    if (max > 1 && window["__consoleShimTest__"] !== false)
    {
        // When first parameter is not a string then add a format string to
        // the argument list so we are able to modify it in the next stop
        if (typeof(args[0]) != "string")
        {
            args.unshift("%o");
            max += 1;
        }

        // For each additional parameter which has no placeholder in the
        // format string we add another placeholder separated with a
        // space character.
        match = args[0].match(/%[a-z]/g);
        for (i = match ? match.length + 1 : 1; i < max; i += 1)
        {
            args[0] += " %o";
        }
    }
    Function.apply.call(log, console, args);
};

// Wrap the native log methods of IE to fix argument output problems
console.log = bind(wrap, window, console.log);
console.debug = bind(wrap, window, console.debug);
console.info = bind(wrap, window, console.info);
console.warn = bind(wrap, window, console.warn);
console.error = bind(wrap, window, console.error);

}

// Implement console.assert if missing
if (!console["assert"])
{
console["assert"] = function()
{
var args = Array.prototype.slice.call(arguments, 0);
var expr = args.shift();
if (!expr)
{
args[0] = "Assertion failed: " + args[0];
console.error.apply(console, args);
}
};
}

// Linking console.dir and console.dirxml to the console.log method if
// missing. Hopefully the browser already logs objects and DOM nodes as a
// tree.
if (!console["dir"]) console["dir"] = console.log;
if (!console["dirxml"]) console["dirxml"] = console.log;

// Linking console.exception to console.error. This is not the same but
// at least some error message is displayed.
if (!console["exception"]) console["exception"] = console.error;

// Implement console.time and console.timeEnd if one of them is missing
if (!console["time"] || !console["timeEnd"])
{
var timers = {};
console["time"] = function(id)
{
timers[id] = new Date().getTime();
};
console["timeEnd"] = function(id)
{
var start = timers[id];
if (start)
{
console.log(id + ": " + (new Date().getTime() - start) + "ms");
delete timers[id];
}
};
}

// Implement console.table if missing
if (!console["table"])
{
console["table"] = function(data, columns)
{
var i, iMax, row, j, jMax, k;

    // Do nothing if data has wrong type or no data was specified
    if (!data || !(data instanceof Array) || !data.length) return;

    // Auto-calculate columns array if not set
    if (!columns || !(columns instanceof Array))
    {
        columns = [];
        for (k in data[0])
        {
            if (!data[0].hasOwnProperty(k)) continue;
            columns.push(k);
        }
    }

    for (i = 0, iMax = data.length; i < iMax; i += 1)
    {
        row = [];
        for (j = 0, jMax = columns.length; j < jMax; j += 1)
        {
            row.push(data[i][columns[j]]);
        }

        Function.apply.call(console.log, console, row);
    }
};

}

// Dummy implementations of other console features to prevent error messages
// in browsers not supporting it.
if (!console["clear"]) console["clear"] = function() {};
if (!console["trace"]) console["trace"] = function() {};
if (!console["group"]) console["group"] = function() {};
if (!console["groupCollapsed"]) console["groupCollapsed"] = function() {};
if (!console["groupEnd"]) console["groupEnd"] = function() {};
if (!console["timeStamp"]) console["timeStamp"] = function() {};
if (!console["profile"]) console["profile"] = function() {};
if (!console["profileEnd"]) console["profileEnd"] = function() {};
if (!console["count"]) console["count"] = function() {};

})();

@kayahr
Copy link
Owner

kayahr commented May 7, 2013

What do you mean with "I am not allowed to do a pullrequest"? I don't know of any pull request restrictions. Anyone can fork the repo and create pull requests. Unfortunately in the current form it is hard to see what exactly you have changed to fix this memory leak. If you really can't create a pull request then can you please post the changes in diff format?

@sigod
Copy link

sigod commented May 8, 2015

Hm. Only difference I can find is this:
var console = (/** @type {Object} */ window.console);
=>
var console = (/* @type {Object} */ window.console);

@sigod
Copy link

sigod commented May 8, 2015

Nah, never mind. #8

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants