Jus*_*tin 24 javascript memory-leaks memory-management exception node.js
根据throw如何在JavaScript中工作的本质,几乎从来没有任何方法可以安全地"拾取你离开的地方",而不会泄漏引用,或者创建一些其他类型的未定义的脆弱状态.
再次在代码示例中,它在第一部分中给出了:
虽然我们已经阻止了突然重启过程,但我们正在疯狂地泄漏资源
我想明白为什么会这样?什么资源泄漏?他们建议您仅使用域来捕获错误并安全地关闭进程.这是所有例外的问题,而不仅仅是在使用域时?在Javascript中抛出和捕获异常是不好的做法吗?我知道这是Python中的常见模式.
编辑
我可以理解为什么如果抛出异常,非垃圾收集语言中可能存在资源泄漏,因为如果抛出异常,您可能运行的任何清理对象的代码都不会运行.
我可以用Javascript想象的唯一原因是抛出一个异常存储引用异常的范围内的变量引用(也许是调用堆栈中的东西),从而保持引用,然后异常对象被保留,从不得到清理.除非所提到的泄漏资源是引擎内部的资源.
UPDATE
我写了一篇博客,现在解释一下这个问题的答案.看看这个
Eri*_*ott 14
您需要担心的是意外的异常.如果您对应用程序的状态不够了解,无法为特定异常添加处理并管理任何必要的状态清理,那么根据定义,您的应用程序的状态是未定义的,并且是不可知的,并且很可能存在事物不应该挂在那周围.这不仅仅是内存泄漏,你不必担心.未知的应用程序状态可能会导致不可预测和不需要的应用程序行为(例如提供错误的输出 - 部分呈现的模板,或不完整的计算结果,或者更糟糕的是,每个后续输出都是错误的情况).这就是为什么在发生未处理的异常时退出进程很重要的原因.它为您的应用程序提供了自我修复的机会.
例外情况发生了,这没关系.接受它.关闭该过程并使用像Forever这样的东西来检测它并将其设置回正轨.集群和域名也很棒.您正在阅读的文本并不是针对抛出异常的注意事项,也不是在您处理了您期望的异常时继续执行该过程 - 这是在发生意外异常时保持流程运行的警告.
B T*_*B T 11
我认为当他们说" 我们正在泄漏资源 "时,他们的确意味着" 我们可能会泄漏资源 ".如果http.createServer正确处理异常,则不应泄漏线程和套接字.但是,如果它不能正确处理事情,它们当然可能是.在一般情况下,您永远不会真正知道某些事情是否始终正确处理错误.
我认为他们错误/非常误导他们说" 通过JavaScript的本质如何在JavaScript中工作,几乎没有任何方法可以安全地...... ".关于throw如何在Javascript(与其他语言相比)中运行起来不应该让它变得不安全.一般来说,抛出/捕获的工作方式也没有什么可以使它不安全 - 除非你使用它们错了.
他们应该说的是,需要妥善处理特殊情况(无论是否使用例外情况).有几个不同的类别可以识别:
一个状态
B.可逆性
C.数据关键性
无论你正在搞砸什么类型的国家,如果你可以扭转局面,你应该这样做而且你已经确定了.问题是不可逆转的状态.如果您可以销毁损坏的数据(或将其隔离以进行单独检查),那么这是不可逆转状态的最佳举措.当抛出异常时,这会自动为局部变量完成,这就是为什么异常在处理纯功能代码中的错误(即没有可能的副作用的函数)方面表现优异的原因.同样,如果可以接受,则应删除任何共享状态或外部状态.在共享状态的情况下,要么抛出异常,直到共享状态变为本地状态,并通过展开堆栈(静态或通过GC)清理,或重新启动程序(我读过人们建议使用某些东西)像nodejitsu永远).对于外部状态,这可能更复杂.
最后一种情况是数据至关重要.好吧,那么你将不得不忍受你创造的错误.每个人都必须处理错误,但是当你的错误涉及到损坏的数据时,它是最糟糕的.这通常需要手动干预(重建丢失/损坏的数据,有选择地修剪等) - 在最后一种情况下,异常处理不会让你全程完成.
我在一些数据存储的多次更新的上下文中写了一个类似的答案,涉及如何处理各种情况下的中间操作失败:https://stackoverflow.com/a/28355495/122422
从node.js文档中获取示例:
var d = require('domain').create();
d.on('error', function(er) {
// The error won't crash the process, but what it does is worse!
// Though we've prevented abrupt process restarting, we are leaking
// resources like crazy if this ever happens.
// This is no better than process.on('uncaughtException')!
console.log('error, but oh well', er.message);
});
d.run(function() {
require('http').createServer(function(req, res) {
handleRequest(req, res);
}).listen(PORT);
});
Run Code Online (Sandbox Code Playgroud)
在这种情况下,handleRequest在关闭套接字之前发生异常时,您正在泄漏连接.
"泄露"的意思是你完成了处理请求而没有事后清理.最终连接将超时并关闭套接字,但如果您的服务器处于高负载状态,它可能会在发生这种情况之前耗尽套接字.
根据您的操作,handleRequest您可能还会泄漏文件句柄,数据库连接,事件监听器等.
理想情况下,您应该处理异常,以便在它们之后进行清理.
| 归档时间: |
|
| 查看次数: |
2992 次 |
| 最近记录: |