Javascript 记录复杂对象时内存泄漏
我目前正忙于编写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
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