博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
libuv使用不当导致的内存泄漏
阅读量:2136 次
发布时间:2019-04-30

本文共 2586 字,大约阅读时间需要 8 分钟。

libuv库使用过程中,发现简单的定时器不关闭对应的句柄会导致内存泄漏;使用文章后面的测试代码缺少uv_close或者uv_loop_close均会导致内存泄漏,关闭的时机也有影响

Detected memory leaks!

Dumping objects ->
{185} normal block at 0x00FB7860, 32 bytes long.
Data: < R z > E8 52 E8 7A 00 00 00 00 00 00 00 00 00 00 00 00
{184} normal block at 0x00FB7818, 8 bytes long.
Data: < > 00 00 00 00 00 00 00 00
{183} normal block at 0x00FB77A8, 48 bytes long.
Data: < > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Object dump complete.

使用VS2010进行调试

1 设置项目依赖
在这里插入图片描述
2 添加泄漏位置的断点
_CrtSetBreakAlloc(185);
根据泄漏报告的位置确定,本例中有3处泄漏, 185, 184, 183,需要调试3次

3 调试代码

打开调用堆栈,发现这里分配的内存4 * 8刚好32字节
uv_default_loop
->uv_loop_init
->uv__loops_add
->uv__realloc
在这里插入图片描述
而这块内存是在uv_loop_close->uv__loop_close->uv__loops_remove中释放的。

同样的方法把分两次设置新的断点位置_CrtSetBreakAlloc(184);_CrtSetBreakAlloc(183);

发现uv_loop_init中有其他两处内存分配

loop->timer_heap = timer_heap = uv__malloc(sizeof(*timer_heap));
lfields = (uv__loop_internal_fields_t*) uv__calloc(1, sizeof(*lfields));

4 解决内存泄漏问题

在头文件查找uv_loop_init,发现有成对的uv_loop_close,在loop结束后调用再次运行发现没有泄漏,问题得到解决,网上找的实例很多都没有说明。

UV_EXTERN int uv_loop_init(uv_loop_t* loop);UV_EXTERN int uv_loop_close(uv_loop_t* loop);

测试代码如下

///*在入口函数中包含 _CrtDumpMemoryLeaks();  即可检测到内存泄露*/#define CRTDBG_MAP_ALLOC  #include 
#include
#ifdef _DEBUG #define new new(_NORMAL_BLOCK, __FILE__, __LINE__) #endif //#include "stdafx.h"#include "uv.h"unsigned int g_tick;unsigned int g_count = 3;void time_cb(uv_timer_t* handle){
unsigned int now = GetTickCount(); printf("last:%lu, now:%lu, time:%lu\n", g_tick, now, now - g_tick); g_tick = now; if (--g_count <= 0) {
uv_timer_stop(handle); uv_close((uv_handle_t*)handle, NULL); }}void EnableMemLeakCheck() {
int tmpFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); tmpFlag |= _CRTDBG_LEAK_CHECK_DF; _CrtSetDbgFlag(tmpFlag); } int _tmain(int argc, _TCHAR* argv[]){
EnableMemLeakCheck(); _CrtSetBreakAlloc(185); //根据泄漏报告的位置确定,本例中有3处泄漏, 185, 184, 183,需要调试3次 /*使用默认loop*/ uv_loop_t *loop = uv_default_loop(); /*创建一个uv_timer_t对象timer*/ uv_timer_t timer; if (loop == NULL) {
printf("init fail, loop:%p\n", loop); return -1; } /*初始化全局变量*/ g_tick = GetTickCount(); /*输出libuv版本*/ printf("uv version:%s\n", uv_version_string()); /*关联timer到loop*/ uv_timer_init(loop, &timer); /*设置定时器参数,包括回调函数,超时时间和重复时间,单位是毫秒*/ uv_timer_start(&timer, time_cb, 1000, 1000); /*loop跑起来*/ uv_run(loop, UV_RUN_DEFAULT); printf("uv_loop_close ...\n"); /*调试内存泄漏时需要注释掉*/ uv_loop_close(loop); getchar(); return 0;}

转载地址:http://lmkgf.baihongyu.com/

你可能感兴趣的文章
Leetcode C++ 《第175场周赛-1 》5332.检查整数及其两倍数是否存在
查看>>
Leetcode C++ 《第175场周赛-2 》5333.制造字母异位词的最小步骤数
查看>>
Leetcode C++ 《第175场周赛-3》1348. 推文计数
查看>>
Leetcode C++《热题 Hot 100-44》102.二叉树的层次遍历
查看>>
Leetcode C++《热题 Hot 100-45》338.比特位计数
查看>>
读书摘要系列之《kubernetes权威指南·第四版》第一章:kubernetes入门
查看>>
Leetcode C++《热题 Hot 100-46》739.每日温度
查看>>
Leetcode C++《热题 Hot 100-47》236.二叉树的最近公共祖先
查看>>
Leetcode C++《热题 Hot 100-48》406.根据身高重建队列
查看>>
《kubernetes权威指南·第四版》第二章:kubernetes安装配置指南
查看>>
Leetcode C++《热题 Hot 100-49》399.除法求值
查看>>
Leetcode C++《热题 Hot 100-51》152. 乘积最大子序列
查看>>
[Kick Start 2020] Round A 1.Allocation
查看>>
Leetcode C++ 《第181场周赛-1》 5364. 按既定顺序创建目标数组
查看>>
Leetcode C++ 《第181场周赛-2》 1390. 四因数
查看>>
阿里云《云原生》公开课笔记 第一章 云原生启蒙
查看>>
阿里云《云原生》公开课笔记 第二章 容器基本概念
查看>>
阿里云《云原生》公开课笔记 第三章 kubernetes核心概念
查看>>
阿里云《云原生》公开课笔记 第四章 理解Pod和容器设计模式
查看>>
阿里云《云原生》公开课笔记 第五章 应用编排与管理
查看>>