如何在Node.js中检测内存泄漏检测

商品编号:
京 东 价:
[定价:¥]
白条分期:
在线客服:
服务支持:
深入浅出Node.js
加载中,请稍候...
商品介绍加载中...
扫一扫,精彩好书免费看
  Node.js让JavaScript在服务器端焕发生机,这是一本带着文艺调调的好看的技术书,书中详细阐述了Node.js的方方面面。如果你是前端工程师,这会是你迈向全端工程师的关键一步。  ——玉伯,支付宝高级技术专家  通过学习Node.js,你可以接触到最新的开发模式与协作思想。通过阅读这本书,你可以在软件开发领域获得广泛而又有深度的收获!所以,我很推荐这本书!  ——庄表伟  从未读过这么让人想一翻到底的Node.js技术读物,看完 “内存控制”这一章后,重新写代码的时候,仿佛都能看到V8是如何进行垃圾回收的。如果你还在纠结callback带来的}}}}}}}嵌套问题,那么推荐你阅读“异步编程”这一章,保证让你大开眼界。世界上本没有嵌套回调,写的人多了,也便有了}}}}}}}。JavaScript已经不仅仅是在浏览器上运行的玩具语言, 它正在通过Node.js进军所有领域。  阅读本书,开启你人生的第一个Node节点吧。  ——Python发烧友,阿里巴巴数据平台技术专家
京东商城向您保证所售商品均为正品行货,京东自营商品开具机打发票或电子发票。
凭质保证书及京东商城发票,可享受全国联保服务(奢侈品、钟表除外;奢侈品、钟表由京东联系保修,享受法定三包售后服务),与您亲临商场选购的商品享受相同的质量保证。京东商城还为您提供具有竞争力的商品价格和,请您放心购买!
注:因厂家会在没有任何提前通知的情况下更改产品包装、产地或者一些附件,本司不能确保客户收到的货物与商城图片、产地、附件说明完全一致。只能确保为原厂正货!并且保证与当时市场上同样主流新品一致。若本商城没有及时更新,请大家谅解!
权利声明:京东上的所有商品信息、客户评价、商品咨询、网友讨论等内容,是京东重要的经营资源,未经许可,禁止非法转载使用。
注:本站商品信息均来自于合作方,其真实性、准确性和合法性由信息拥有者(合作方)负责。本站不提供任何保证,并不承担任何法律责任。
加载中,请稍候...
jd_134023nee(四川)
jd_tao258(山东)
wircowave(北京)
QJPolly(北京)
风一般de侽子(四川)
jd_6ff7bbaa2c182(浙江)
morecho(上海)
fbishawei(辽宁)
加载中,请稍候...
加载中,请稍候...
加载中,请稍候...
加载中,请稍候...
加载中,请稍候...
加载中,请稍候...
浏览了该商品的用户还浏览了
加载中,请稍候...
七日畅销榜
新书热卖榜
iframe(src='///ns.html?id=GTM-T947SH', height='0', width='0', style='display: visibility:')如何自己检查NodeJS的代码是否存在内存泄漏_百度知道
如何自己检查NodeJS的代码是否存在内存泄漏
提问者采纳
首先,我们检查了代码,发现所有的代码都是用new来分配内存,用delete来释放内存。那么,我们能够用一个全程替换,来替换掉所有的new和delete操作符吗?不能。因为代码的规模太大了,那样做除了浪费时间没有别的任何好处。好在我们的源代码是用C++来写成的,所以,这意味着没有必要替换掉所有的new和delete,而只用重载这两个操作符。对了,值用重载这两个操作符,我们就能在分配和释放内存之前做点什么。这是一个绝对的好消息。我们也知道该如何去做。因为,MFC也是这么做的。我们需要做的是:跟踪所有的内存分配和交互引用以及内存释放。我们的源代码使用Visual C++写成,当然这种解决方法也可以很轻松的使用在别的C++代码里面。要做的第一件事情是重载new和delete操作符,它们将会在所有的代码中被使用到。我们在stdafx.h中,加入:
#ifdef _DEBUG
inline void * __cdecl operator new(unsigned int size,
const char *file, int line)
inline void __cdecl operator delete(void *p)
#endif这样,我们就重载了new和delete操作符。我们用$ifdef和#endif来包住这两个重载操作符,这样,这两个操作符就不会在发布版本中出现。看一看这段代码,会发现,new操作符有三个参数,它们是,分配的内存大小,出现的文件名,和行号。这对于寻找内存泄漏是必需的和重要的。否则,就会需要很多时间去寻找它们出现的确切地方。加入了这段代码,我们的调用new()的代码仍然是指向只接受一个参数的new操作符,而不是这个接受三个参数的操作符。另外,我们也不想记录所有的new操作符的语句去包含__FILE__和__LINE__参数。我们需要做的是自动的让所有的接受一个参数的new操作符调用接受三个参数的new操作符。这一点可以用一点点小的技巧去做,例如下面的这一段宏定义,
#ifdef _DEBUG
#define DEBUG_NEW new(__FILE__, __LINE__)
#define DEBUG_NEW new
#define new DEBUG_NEW
现在我们所有的接受一个参数的new操作符都成为了接受三个参数的new操作符号,__FILE__和__LINE__被预编译器自动的插入到其中了。然后,就是作实际的跟踪了。我们需要加入一些例程到我们的重载的函数中去,让它们能够完成分配内存和释放内存的工作。这样来做, #ifdef _DEBUG
inline void * __cdecl operator new(unsigned int size,
const char *file, int line)
{void *ptr = (void *)malloc(size);AddTrack((DWORD)ptr, size, file, line);return(ptr);
inline void __cdecl operator delete(void *p)
{RemoveTrack((DWORD)p);free(p);
#endif另外,还需要用相同的方法来重载new[]和delete[]操作符。这里就省略掉它们了。最后,我们需要提供一套函数AddTrack()和RemoveTrack()。我用STL来维护存储内存分配记录的连接表。这两个函数如下:
typedef struct {DWORDDWORDchar file[64];DWORD
} ALLOC_INFO;
typedef list&ALLOC_INFO*& AllocL
AllocList *allocL
void AddTrack(DWORD addr, DWORD asize, const char *fname, DWORD lnum)
{ALLOC_INFO *if(!allocList) {allocList = new(AllocList);}info = new(ALLOC_INFO);info-&address =strncpy(info-&file, fname, 63);info-&line =info-&size =allocList-&insert(allocList-&begin(), info);
void RemoveTrack(DWORD addr)
{AllocList::if(!allocList)for(i = allocList-&begin(); i != allocList-&end(); i++){if((*i)-&address == addr){allocList-&remove((*i));}}
现在,在我们的程序退出之前,allocList存储了没有被释放的内存分配。为了看到它们是什么和在哪里被分配的,我们需要打印出allocList中的数据。我使用了Visual C++中的Output窗口来做这件事情。
void DumpUnfreed()
{AllocList::DWORD totalSize = 0;char buf[1024];if(!allocList)for(i = allocList-&begin(); i != allocList-&end(); i++) {sprintf(buf, &%-50s: LINE %d, ADDRESS %d %d unfreed &,(*i)-&file, (*i)-&line, (*i)-&address, (*i)-&size);OutputDebugString(buf);totalSize += (*i)-&}sprintf(buf, &----------------------------------------------------------- &);OutputDebugString(buf);sprintf(buf, &Total Unfreed: %d bytes &, totalSize);OutputDebugString(buf);
现在我们就有了一个可以重用的代码,用来监测跟踪所有的内存泄漏了。这段代码可以用来加入到所有的项目中去。虽然它不会让你的程序看起来更好,但是起码它能够帮助你检查错误,让程序更加的稳定。
来自团队:
其他类似问题
为您推荐:
内存泄漏的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁酷勤网 C 程序员的那点事!
当前位置: >
浏览次数:次
在Storify,我们用Node.js驱动后台。
对于大多数生产环境上的问题(像未捕获的异常),我们使用日志来调试。然后我们看到了一些其他的BUG,像内存泄漏和无限循环,这些漏洞无法通过debugging工具来调试。
注* 关于在Node.JS中添加错误日志,可参考:
过去,当我们的服务变得很慢时,我们使用Monit去重启他们。当我们上线了Livefyre之后,我们决定不要重启,尝试去修复这些缺陷。经过几个月的尝试,我们在Node.JS的调试技巧方面学到了很多。
几个月以前,我们已经知道程序有内存泄漏,这会引起我们的服务器强制自动重启。因为我们使用了大约60个npm 模块,这个BUG也有可能是从这些模块里产生的,因此找到泄漏点是不太可能的。
我们的同事@devongovett决定去修这个BUG,但是他不知道从何开始。
Devon创建了一台服务器去记录Node.JS的内存使用情况。他的第一个发现是在一条查询query执行后,几个对象被遗留了下来。下一步是将大量的Mongoose注释掉去寻找泄漏点。最终他找到了罪魁祸首。
&我认为这纯碎是运气&
这个调试经验让我们坚信我们需要使用更好的调试工具。
我们的服务会偶尔当机几分钟。@tjfontaine Node.js项目的主管开始解决调试工具的问题,他建议我们试试MDB。在阅读了这篇文章之后,我们开始玩这个工具了。
我使用gcare去获取核心转储(core dump),上传到Mana并开始分析。我的第一个分析很全面,但是我无法理解这个进程在干什么。
[ 00007fffex7f7a24ced619() ]
00007fffe496a1d0 uv__io_poll+0x148()
00007fffe496a230 uv_run+0xd8()
00007fffe496a2b0 _ZN4node5StartEiPPc+0x150()
f7a24c1e76d()
我在进程没有干什么任何事情的时侯捕获到了。
Node.js在等待事件发生时就会干这个。
最扯蛋的是gcare在你的程序崩溃的时侯进程了转储捕获(capture the dump)。这里有几个选项可以获取有用的跟踪。
在一段特定的代码处引导核心
process.abort()
在未捕获异常时引导核心
node --abort-on-uncaught-exception app.js
当CPU楔入(wedging)时杀死进程
kill -ABRT $pid
我们第一个有用的跟踪
通过使用 kill -ABRT method,我最终可以获取到一个好的跟踪栈。
我会只关注最重要的部分,但是你可以在这里看到整个栈。
& 00007ffffd09c0c0::jsstack
7ffffd09c7c0 0x3bdddc420285 inlineContent (e)
7ffffd09c810 0x3bddc784e83d juice (eb9)
7ffffd09c948 0x3bddc4fb80f0 renderWrapper (270dfadc0769)
7ffffd09cdb8 0x3bddc7f2858b forEach (28a6e1015579)
7ffffd0a0ac0 node::Start+0x172
通过这个跟踪,我们开始注意Juice, 这是我们用来为RSS订阅源生成内联CSS的一个库(注* 邮件一般无法外联CSS样式)。我们只在Webapp代码里使用了一次。像下面这样:
async.forEach(stories, function(story, cb) {
res.render(&story/_minimal&, {
}, function(e, html) {
if (e) return cb(e);
var description = juice(html, someCss);
});}, callback);
通过这个,我现在可以在本地重现这个挂起了。最终的研究我们发现问题出现在了Jsdom,这个库在处理大量HTML文档时会非常慢。相比修复Jsdom,我们开始寻找快一点的模块。通过使用Cheerio和Styliner我们现在可以将处理过程压缩到3秒以内,但是Juice需要大概5分钟。
我希望用这个工具找到mongoose的泄漏。现在我们可以直接找到bug,不需要猜了。
有些漏洞无法在非生产环境发现。找到一种可以在生产环境检测程序工作的工具非常重要。
现在我们在重启前都会使用Monit去自动检测核心转储:
stop program = &/bin/bash -c &/bin/kill -ABRT `/bin/cat &%= processpidfile %&`&&
然后我们将Manit的日志跟Hipchat连在一起。现在我们明白重启时什么发生什么。
希望这篇文章对你有所帮助。
& 相关主题:OurJS-我们的JS, 我们的技术-IT文摘; 专注JS相关领域;
我们热爱编程, 我们热爱技术;我们是高大上, 有品味的码农;
欢迎您订阅我们的技术周刊
我们会向您分享我们精心收集整理的,最新的行业资讯,技术动态,外文翻译,热点文章;
我们使用第三方邮件列表向您推送,我们不保存您的任何个人资料,注重您的隐私,您可以随时退订,
欢迎分享您的观点,经验,技巧,心得
让我们一起找寻程序员的快乐,探索技术, 发现IT人生的乐趣;
本网站使用缓存技术每次加载仅需很小流量, 可在手机中流畅浏览;
如果您发现任何BUG,请即时告知我们: ourjs(
订阅邮件周刊
Debug调试Node.JS:我们是如何定位内存泄漏和无限循环的
注意 转载须保留原文链接,译文链接,作者译者等信息。&&
在Storify,我们用Node.js驱动后台。对于大多数生产环境上的问题(像未捕获的异常),我们使用日志来调试。然后我们看到了一些其他的BUG,像内存泄漏和无限循环,这些漏洞无法通过debugging工具来调试。注* 关于在Node.JS中添加错误日志,可参考: 过去,当我们的服务变得很慢时,我们使用 去重启他们。当我们上线了Livefyre之后,我们决定不要重启,尝试去修复这些缺陷。经过几个月的尝试,我们在Node.JS的调试技巧方面学到了很多。内存泄漏几个月以前,我们已经知道程序有内存泄漏,这会引起我们的服务器强制自动重启。因为我们使用了大约60个 ,这个BUG也有可能是从这些模块里产生的,因此找到泄漏点是不太可能的。我们的同事@devongovett决定去修这个BUG,但是他不知道从何开始。Devon创建了一台服务器去记录Node.JS的内存使用情况。他的第一个发现是在一条查询query执行后,几个对象被遗留了下来。下一步是将大量的Mongoose注释掉去寻找泄漏点。最终他找到了罪魁祸首。“我认为这纯碎是运气”这个调试经验让我们坚信我们需要使用更好的调试工具。CPU占用率我们的服务会偶尔当机几分钟。@tjfontaine Node.js项目的主管开始解决调试工具的问题,他建议我们试试&。在阅读了这篇文章之后,我们开始玩这个工具了。首次尝试我使用gcare去获取核心转储(core dump),上传到Mana并开始分析。我的第一个分析很全面,但是我无法理解这个进程在干什么。[ 00007fffex7f7a24ced619() ]00007fffe496a1d0 uv__io_poll+0x148()00007fffe496a230 uv_run+0xd8()00007fffe496a2b0 _ZN4node5StartEiPPc+0x150()f7a24c1e76d()我在进程没有干什么任何事情的时侯捕获到了。Node.js在等待事件发生时就会干这个。最扯蛋的是gcare在你的程序崩溃的时侯进程了转储捕获(capture the dump)。这里有几个选项可以获取有用的跟踪。在一段特定的代码处引导核心process.abort()在未捕获异常时引导核心node --abort-on-uncaught-exception app.js当CPU楔入(wedging)时杀死进程kill -ABRT $pid我们第一个有用的跟踪通过使用 kill -ABRT method,我最终可以获取到一个好的跟踪栈。我会只关注最重要的部分,但是你可以在看到整个栈。& 00007ffffd09c0c0::jsstack[...]7ffffd09c7c0 0x3bdddc420285 inlineContent (e)7ffffd09c810 0x3bddc784e83d juice (eb9)[...]7ffffd09c948 0x3bddc4fb80f0 renderWrapper (270dfadc0769)[...]7ffffd09cdb8 0x3bddc7f2858b forEach (28a6e1015579)[...]7ffffd0a0ac0 node::Start+0x172通过这个跟踪,我们开始注意Juice, 这是我们用来为RSS订阅源生成内联CSS的一个库(注* 邮件一般无法外联CSS样式)。我们只在Webapp代码里使用了一次。像下面这样:async.forEach(stories, function(story, cb) {& & res.render(‘story/_minimal’, {& & & & //…& & }, function(e, html) {& & & & if (e) return cb(e);& & & & var description = juice(html, someCss);& & & & // …& & });}, callback);通过这个,我现在可以在本地重现这个挂起了。最终的研究我们发现问题出现在了 ,这个库在处理大量HTML文档时会非常慢。相比修复Jsdom,我们开始寻找快一点的模块。通过使用 &和 &我们现在可以将处理过程压缩到3秒以内,但是Juice需要大概5分钟。结论我希望用这个工具找到mongoose的泄漏。现在我们可以直接找到bug,不需要猜了。有些漏洞无法在非生产环境发现。找到一种可以在生产环境检测程序工作的工具非常重要。现在我们在重启前都会使用Monit去自动检测核心转储:stop program = “/bin/bash -c ‘/bin/kill -ABRT `/bin/cat &%= processpidfile %&`’”然后我们将Manit的日志跟Hipchat连在一起。现在我们明白重启时什么发生什么。希望这篇文章对你有所帮助。
原文地址:
&热门文章 - 分享最多
&相关阅读 - JS学习
&关键字 - Node.JS
&欢迎订阅 - 技术周刊
我们热爱编程, 我们热爱技术; 我们是高端, 大气, 上档次, 有品味, 时刻需要和国际接轨的码农; 欢迎您订阅我们的技术周刊; 您只需要在右上角输入您的邮箱即可; 我们注重您的隐私,您可以随时退订.
加入我们吧! 让我们一起找寻码农的快乐,探索技术, 发现IT人生的乐趣;
我们的微信公众号: ourjs-com
打开微信扫一扫即可关注我们:
IT文摘-程序员(码农)技术周刊 上传我的文档
 下载
 收藏
该文档贡献者很忙,什么也没留下。
 下载此文档
正在努力加载中...
给Node.js新手的7个建议技巧
下载积分:800
内容提示:给Node.js新手的7个建议技巧
文档格式:DOCX|
浏览次数:1|
上传日期: 20:00:12|
文档星级:
该用户还上传了这些文档
给Node.js新手的7个建议技巧
官方公共微信

我要回帖

更多关于 内存泄漏检测 的文章

 

随机推荐