当前位置: 首页 > news >正文

仙居网站设计/深圳最好seo

仙居网站设计,深圳最好seo,网站建设的 文献综述,全国公共资源交易平台官网内存泄漏 内存泄漏的核心原因是调用分配与释放时没有符合开闭原则。有分配却没有释放,这自然会使得进程的堆内存会越来越少,直到耗尽。 一个内存泄漏检测工具需要能够精准地定位到泄漏是由代码中的哪一行所引起的。 可以直接使用一些现成的工具进行内…

内存泄漏

内存泄漏的核心原因是调用分配与释放时没有符合开闭原则。有分配却没有释放,这自然会使得进程的堆内存会越来越少,直到耗尽。

一个内存泄漏检测工具需要能够精准地定位到泄漏是由代码中的哪一行所引起的。

可以直接使用一些现成的工具进行内存泄漏的排查,比如valgrind、mtrace、ASAN等等。但这些工具往往不适用于在生成环境中实时地检测内存泄漏,而多是用于在发现内存泄漏后进行测试。特别是valgrind和ASAN对性能的影响也比较大,而且不适用于嵌入式系统。

那么,是否可以自己写一些小工具,对mallocfree做一些简单的跟踪,然后可以随时比较直观地查看是否有内存泄漏呢?

跟踪malloc和free

显然,要检测内存泄漏最基本的思路就是对mallocfree的调用情况进行记录,调用malloc返回一个地址时,对该地址增加一条记录,然后对该地址调用free时,则撤销该记录。最后程序正常运行结束后,还保留下来的那些记录就是内存泄漏的证据了。

首先想到的就是加hook。那么为什么不能像死锁检测组件那样,用dlsym直接对mallocfree加钩子呢?

大量的函数如printf等等本身内部存在调用malloc,在我们重写malloc时难以避免会使用这些函数,这可能引起递归调用:

malloc()...sprintf()...malloc()....

使用宏定义替换

那怎么办呢?可以考虑用宏定义去替换malloc,比如这样:

void* __malloc(size_t size, const char* file, int line) {/*...*/malloc(size);/*...*/
}void __free(void* ptr, const char* file, int line) {/*...*/free(ptr);/*...*/
}#define malloc(size) __malloc(size, __FILE__, __LINE__)
#define free(ptr) __free(ptr, __FILE__, __LINE__)

这样一来在该宏定义之后,调用mallocfree时实际就是调用__malloc__free了。并且因为这两个函数都传入了文件名和调用位置,因此可以很方便地查看出是在哪些位置调用了某个malloc。

修改后的测试代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>void* __malloc(size_t size, const char* file, int line) {void* p = malloc(size);printf("malloc: [%s, line %d]@%p size=%lu\n", file, line, p, size);return p;
}void __free(void* ptr, const char* file, int line) {printf("free: [%s, line %d]@%p\n", file, line, ptr);free(ptr);
}
#define malloc(size) __malloc(size, __FILE__, __LINE__)
#define free(ptr) __free(ptr, __FILE__, __LINE__)int main() {char* s1 = (char*)malloc(10);char* s2 = (char*)malloc(20);free(s1);free(s2);return 0;
}

打印输出:

malloc: [memleak_detector.c, line 24]@0x555555756260 size=10
malloc: [memleak_detector.c, line 25]@0x555555756690 size=20
free: [memleak_detector.c, line 27]@0x555555756260
free: [memleak_detector.c, line 28]@0x555555756690

可以正常打印出malloc调用的位置,非常直观。但这种方法有一点不太好,就是每一个需要替换malloc的源文件都要单独用宏进行替换。可以将其封装成头文件memleak_detector.h,然后通过一个宏__MALLOC_DEBUG来控制:

#include <unistd.h>
void* __malloc(size_t size, const char* file, int line);
void __free(void* ptr, const char* file, int line);#ifdef __MALLOC_DEBUG
#define malloc(size) __malloc(size, __FILE__, __LINE__)
#define free(ptr) __free(ptr, __FILE__, __LINE__)
#endif

在源文件中包含该头文件:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>#define __MALLOC_DEBUG  // 放在所有头文件之后
#include "memleak_detector.h"
int main() {......
}

现在我们都能够成功地“截获”了mallocfree的调用,接下来就看如何把这些记录下来了。

记录内存泄漏时的malloc位置

光光通过看打印的方式来查是否存在内存泄漏显然很不方便。因此我们需要将其记录下来,以便程序长时间运行后进行排查。

如果只是临时记录,那么有很多方法,比如我们可以将malloc的记录保存到链表、哈希表等等结构,然后在free时删除对应记录,那么最终留下来的记录就表明出现了内存泄漏。但是这些数据是保存在内存中的,一旦进程结束,就消失了。

我们不妨采用文件来记录,用malloc申请到的地址给文件命名,一次malloc就产生一个文件,其中记录了我们前面的打印信息,然后对应地在free时删除这个文件。这样一来,即使程序终止了,文件也会保存下来,就可以很方便地查看了。

于是修改__malloc__free如下:

void* __malloc(size_t size, const char* file, int line) {void* p = malloc(size);if(p) { // 首先确保成功申请到了内存char buf[256] = {0};char filename[64] = {0};snprintf(filename, 63, "mem/%p.mem", p);int len = snprintf(buf, 255, "[%s, line %d] size=%lu\n", file, line, size);int fd = open(filename, O_RDWR | O_CREAT, S_IRUSR);if(fd < 0) {printf("open %s failed in __malloc.\n", filename);}else {write(fd, buf, len);	// 写入到文件close(fd);}}return p;
}void __free(void* ptr, const char* file, int line) {char filename[64] = {0};snprintf(filename, 63, "mem/%p.mem", ptr);if(unlink(filename) < 0) {  // 使用 unlink 来删除文件printf("[%s, line %d] %p double free!\n", file, line, ptr);}free(ptr);
}

测试

我们在代码中为s1s2申请内存,但不释放s2的内存:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>#define __MALLOC_DEBUG  // 放在所有头文件之后
#include "memleak_detector.h"
int main() {char* s1 = (char*)malloc(10);char* s2 = (char*)malloc(20);free(s1);//free(s2);return 0;
}

在运行之前,需在程序的运行目录下创建mem目录,运行后mem目录下产生了一个文件0x555555757280.mem,使用cat查看其内容:

[memleak_demo.c, line 11] size=20

可以正确地查看到malloc调用的位置。

http://www.lbrq.cn/news/1580689.html

相关文章:

  • 昌乐做网站/建设公司网站大概需要多少钱?
  • 专业海外网站推广/一键优化免费下载
  • 网站建设方案格式/百度提交网站收录入口
  • 网站布局的好坏的几个要素/手机百度如何发布作品
  • 腾讯云做wordpress太卡/济南优化网站的哪家好
  • 如何用word做网站/百度搜索引擎的特点
  • 网站设计与网络客服/淄博seo培训
  • 天津南洋建设集团网站/新产品推广
  • 丹江口做网站/网店产品seo如何优化
  • 网站怎么弄实名制认证/营销网络
  • 网站备案接入商/关键词优化是什么意思
  • 重庆微信网站建设多少钱/百度下载app下载安装
  • 合肥做网站/谷歌google搜索引擎入口
  • 越南做It网站推广/被公司优化掉是什么意思
  • 免费cms/深圳知名seo公司
  • 兰州网站制作cheng/旅游景区网络营销案例
  • 猫眼网站建设/网站页面
  • 余姚网站推广/免费seo在线工具
  • 石家庄商城网站建设/东莞网站快速排名提升
  • 专业郑州做网站/网址
  • 如何查看网站服务器时间/如何做好网上销售
  • 广州黄埔区做网站培训机构/线上推广方案怎么写
  • 郑州手机端网站建设/软媒win7优化大师
  • 云浮市住房城乡建设信息网网站/北京百度推广优化公司
  • 公司的网站开发费计入什么科目/苏州百度推广服务中心
  • 克隆网站后怎么做/快速排名程序
  • 技术支持 东莞网站建设母婴护理/免费建立个人网站
  • 深圳网站建设营销服务平台/广州百度推广客服电话
  • 手机版网站怎么做/网站推广的工作内容
  • 深圳网站建设公司那家好/网站seo关键词排名
  • YOLOv6深度解析:实时目标检测的新突破
  • 个人效能是一个系统
  • 原创邮件合并Python工具使用说明(附源码)
  • Amazon Linux 训练lora模型的方式
  • [激光原理与应用-202]:光学器件 - 增益晶体 - Nd:YVO₄增益晶体的制造过程与使用过程
  • IDEA快捷键壁纸分享