Javascript 记录复杂对象时内存泄漏

Javascript 记录复杂对象时内存泄漏,javascript,memory-leaks,Javascript,Memory Leaks,我目前正忙于编写javascript库。在这个库中,我想提供一些关于控制台的日志记录 function log () { if ((window && typeof (window.console) === "undefined") || !enableLogging) { return false; } function currentTime() { var time = new

我目前正忙于编写javascript库。在这个库中,我想提供一些关于控制台的日志记录

function log () {
        if ((window && typeof (window.console) === "undefined") || !enableLogging) {
            return false;
        }

        function currentTime() {
            var time = new Date();
            return time.getHours() + ':' + time.getMinutes() + ':' + time.getSeconds() + '.' + time.getMilliseconds();
        }

        var args = [];

        args.push(currentTime());

        for (var i = 1; i < arguments.length; i++) { 
            args.push(arguments[i]);
        }

        switch (arguments[0]) {
            case severity.exception:
                if (window.console.exception) {
                    window.console.exception.apply(console, args);
                } else {
                    window.console.error.apply(console, args);
                }
                break;
            case severity.error:
                window.console.error.apply(console, args);
                break;
            case severity.warning:
                window.console.warning.apply(console, args);
                break;
            case severity.information:
                window.console.log.apply(console, args);
                break;
            default:
                window.console.log.apply(console, args);
        }
        return true;
    }

现在的问题是,这会导致内存泄漏。问题是我传递的对象通过console.log方法留在内存中。有没有办法避免这种情况或清除这种情况?

可以理解的是,传递到
控制台.log
的对象没有GC,因为您需要能够在代码运行后在开发人员工具中检查它们。我不认为这是一个问题,因为在调试应用程序时需要这样做,但生产代码不应该做任何控制台日志记录

如果您仍然需要在生产中记录资料(或将其发送到某处),我建议您使用以下对象:

console.log(JSON.stringify(db, null, '\t'));  // '\t' to pretty print
这里的额外好处是,您可以在记录时(在记录对象引用1时)真正捕获对象的状态

由于您正在尝试记录大型对象,请注意这样做可能会降低性能,因此如果您想在生产环境中这样做,请三思


1-似乎在最新的Chrome中,
args
变量应该在执行
log
后进行垃圾收集,不需要设置为
null
。然而,该数组的项被传递到
console.log
,它们永远保存在那里——如果它们是复杂的主机对象(如数据库事务),则可能是您的泄漏。或者,
.apply
控制台
方法上调用时会泄漏,您在哪个浏览器中测试了它?您没有将
参数
引用设置为null,但是
args
变量?我知道,但这没有什么区别。当我将参数设置为null时,我的漏洞就被解决了,但我不能这样做,因为在严格模式下是不允许的。我的发现来自谷歌Chrome。在你的代码中,唯一可能导致内存泄漏的地方是
currentTime
函数,但当
log
函数返回时,它应该会得到GC'd。请尝试
var currentTime=function(){…}
,但这很难实现。这应该没有什么区别。你确定GC运行了吗?这可能需要几秒钟。当函数返回时,
arguments
变量将被丢弃,从而释放对它所包含的外部对象的任何引用。奇怪。嗨,你的解释听起来很合理。我从来没有那样看它。谢谢你的评论。当开发人员启用日志功能时,我将添加一个额外的警告,以便他们意识到风险,不要在生产中使用它。我通常在所有日志/调试工具周围使用一个小的包装功能,如果站点在生产环境中运行,它只会丢弃所有浏览器日志输入,有时还会检查是否存在错误“调试”查询参数覆盖,以便我可以与有问题的特定用户一起工作。这可以避免内存泄漏,降低意外记录敏感数据的风险,提高性能(至少略微提高),并减少“足够了解”的管理人员、测试人员和用户不必要的担忧。@brichins这是离题的,但当用户有问题时,您如何解决问题?@DmitryPashkevich仍然有单独运行的分析,以便我可以获得远程错误报告。显然,这不是一个适合所有人的解决方案-我通常在封闭环境中工作,而不是在一般公众使用的网站上工作,因此,如果网站存在分析无法发现的问题,我可以直接与特定用户合作。我发送他们(或屏幕共享并控制)到
/?debug
,环境感应脚本会记录查询参数
debug
的存在,并重新打开日志记录和其他诊断功能。
console.log(JSON.stringify(db, null, '\t'));  // '\t' to pretty print