18 | 案例篇:内存泄漏了,我该如何定位和处理?
该思维导图由 AI 生成,仅供参考
内存的分配和回收
- 深入了解
- 翻译
- 解释
- 总结
本文介绍了如何定位和处理内存泄漏的问题。作者首先回顾了内存的分配和回收方式,包括栈和堆内存的分配与释放。然后详细讨论了内存泄漏的危害,指出内存泄漏会导致系统性能问题,并介绍了如何使用vmstat工具观察内存变化情况。接着,通过一个斐波那契数列的案例演示了如何检测内存泄漏并进行定位和处理。最后,作者提供了在Ubuntu 18.04系统上运行案例的具体步骤和命令。整体而言,本文以案例为引导,结合具体工具和命令,帮助读者了解内存泄漏问题的定位和处理方法。 文章通过介绍内存泄漏的危害、使用vmstat工具观察内存变化情况以及演示如何检测内存泄漏并进行定位和处理,为读者提供了全面的解决方案。同时,作者还提到了使用memleak工具来跟踪内存分配和释放请求,并指出了在容器中运行时可能遇到的问题以及解决方法。最后,文章总结了修复内存泄漏的方法,并鼓励读者养成良好的编程习惯,以避免内存泄漏的发生。整体而言,本文内容详实,适合开发人员和系统管理员阅读,对于定位和处理内存泄漏问题有很好的指导作用。
《Linux 性能优化实战》,新⼈⾸单¥68
全部留言(125)
- 最新
- 精选
- Scott我比较关心老版本的Linux怎么做同样的事,毕竟没有办法升级公司服务器的内核。
作者回复: 另一个用的比较多的是valgrind
2019-01-01357 - 睡在床板下谈谈自己生产环境运行3个月的内存泄露经验吧: 现象:服务程序运行90天,监控系统告警内存达到阈值,内存泄漏800M。现实:生产环境、难复现。 - 保存core文件。 统计top10 大小块内存分配百分比 - 发现20字节大小内存申请了 3700w次,大概700M - 通过工具搜索已有符号文件中大小为20字节的结构体、类,但是可能包含第三方库、组件没有符号文件,导致分析遇阻,未果 - 通过随机抽查20字节内存地址内容,希望找到有效信息,但几乎都是 0x00 0x10 0x00 , 没字符串,猜不出什么内容,未果 - 通过3700w次数申请,平均每小时17000次左右。 通过完善的日志系统,分析1w~3w量级的消息,大概4个,review代码,问题解决 - 问题定位总共花费了4个小时左右。分析内存泄漏工具、方法很多,但是我觉的更重要的是完善的监控系统和日志系统。
作者回复: 谢谢分享!的确,完善的监控和日志可以更快排查和定位问题,我们专栏后面也有文章提到监控的一些思路。
2020-07-20734 - Maxwell如果是java应用程序,也可以用这个方法定位么?
作者回复: Java 看到的是JVM 的堆栈。其实,jmap这些Java原生的工具更好用
2019-01-02621 - 阿卡牛老师,你这个例子是已经知道哪个进程有内存泄露了,请问如何找出哪个进程呢?
作者回复: 去掉进程号选项
2019-01-04412 - 姜小鱼老师,memleak只能检测用户程序的内存泄漏吧?如果检测内核态谋和模块内存泄漏呢,Kmemleak能否讲一下呢?
作者回复: 也支持内核的,看它的源码可以发现,kmalloc/kfree/kmem_cache_alloc等等也都在TRACEPOINT_PROBE里面
2019-05-074 - Vicky🐣🐣🐣1. 如果执行/usr/share/bcc/tools/memleak -a -p [pid] 就会报错Exception: Failed to attach BPF to uprobe 但是执行/usr/share/bcc/tools/memleak -a,就不会报错,但是里面并没有和app相关函数 2. free观察情况如下,新机器,并没有任何其他高占用内存的进程,很是奇怪 procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 1 0 0 218244 112044 463144 0 0 21 31 148 344 1 0 99 0 0 0 0 0 218268 112044 463144 0 0 0 0 168 402 0 1 99 0 0 0 0 0 217928 112044 463144 0 0 0 7 182 427 1 0 99 0 0 0 0 0 217836 112044 463228 0 0 23 0 317 730 1 1 98 0 0 0 0 0 217836 112048 463236 0 0 0 17 186 437 1 0 99 0 0 0 0 0 215804 112052 463232 0 0 0 19 202 476 1 1 98 0 0 0 0 0 215860 112052 463240 0 0 0 5 221 490 1 1 99 0 0 0 0 0 217040 112056 463244 0 0 0 15 207 481 1 0 99 0 0 0 0 0 217040 112056 463244 0 0 0 0 156 363 0 0 100 0 0 0 0 0 76976 112056 463296 0 0 24 12 221 546 11 3 86 0 0 0 0 0 77008 112060 463316 0 0 0 11 178 407 1 1 98 0 0 0 0 0 75140 112060 463324 0 0 0 27 176 812 2 3 95 0 0 0 0 0 74584 112060 463328 0 0 0 7 174 819 1 1 98 0 0 0 0 0 74616 112060 463332 0 0 0 0 183 417 0 0 99 0 0 0 0 0 216884 112060 463332 0 0 0 83 176 403 1 0 98 1 0 0 0 0 216884 112064 463328 0 0 0 9 180 448 0 1 99 0 0 0 0 0 217012 112064 463336 0 0 0 4 193 452 0 1 99 0 0
作者回复: 看一下内核配置开启CONFIG_UPROBE_EVENTS了吗?
2019-02-2343 - Vicky🐣🐣🐣老师,很多同学都问这个问题了,麻烦解答一下吧 ubuntu 4.15.0-29 # /usr/share/bcc/tools/memleak -a -p 21642 Attaching to pid 21642, Ctrl+C to quit. perf_event_open(/sys/kernel/debug/tracing/events/uprobes/p__lib_x86_64_linux_gnu_libc_2_27_so_0x97070_21642_bcc_21882/id): Input/output error Traceback (most recent call last): File "/usr/share/bcc/tools/memleak", line 416, in <module> attach_probes("malloc") File "/usr/share/bcc/tools/memleak", line 406, in attach_probes pid=pid) File "/usr/lib/python2.7/dist-packages/bcc/__init__.py", line 989, in attach_uprobe raise Exception("Failed to attach BPF to uprobe") Exception: Failed to attach BPF to uprobe
作者回复: 内核中需要开启 CONFIG_UPROBE_EVENTS=y
2019-02-2343 - 唯安格老师,我运行:$ /usr/share/bcc/tools/memleak -a -p $(pidof app) 并没有看到内存泄漏的问题。之后还看了app的源码。源码内的确没有调用free()函数。请问这可能是什么情况? root@ubuntu:/# /usr/share/bcc/tools/memleak -p $(pidof app) -a Attaching to pid 84307, Ctrl+C to quit. [02:42:22] Top 10 stacks with outstanding allocations: [02:42:27] Top 10 stacks with outstanding allocations: [02:42:32] Top 10 stacks with outstanding allocations: [02:42:37] Top 10 stacks with outstanding allocations: [02:42:43] Top 10 stacks with outstanding allocations: [02:42:48] Top 10 stacks with outstanding allocations: [02:42:53] Top 10 stacks with outstanding allocations: [02:42:58] Top 10 stacks with outstanding allocations: [02:43:03] Top 10 stacks with outstanding allocations: ^Croot@ubuntu:/# docker exec app cat /app.c #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <unistd.h> long long *fibonacci(long long *n0, long long *n1) { long long *v = (long long *) calloc(1024, sizeof(long long)); *v = *n0 + *n1; return v; } void *child(void *arg) { long long n0 = 0; long long n1 = 1; long long *v = NULL; for (int n = 2; n > 0; n++) { v = fibonacci(&n0, &n1); n0 = n1; n1 = *v; printf("%dth => %lld\n", n, *v); sleep(1); } } int main(void) { pthread_t tid; pthread_create(&tid, NULL, child, NULL); pthread_join(tid, NULL); printf("main thread exit\n"); return 0;
作者回复: 去掉进程号选项-p试试?
2019-03-122 - 元天夫还有一个很low的问题,Linux version 2.6.32-504.23.4.el6.x86_64 (mockbuild@c6b9.bsys.dev.centos.org) (gcc version 4.4.7 20120313 (Red Hat 4.4.7-11),这个是我查看的内核信息,这个显示内核版本是4.4.7对吗?
作者回复: 4.4.7是Red Hat产品的版本,内核版本是2.6.32
2019-02-2222 - 元天夫老师,请教个问题,pmap -x下,看到有的输出项的脏页数比较大,有104万,这个算大吗
作者回复: 看场景,比如一般的I/O密集型的应用,脏页大一些可能是正常的;但有些数据一致性要求比价高的应用,可能希望尽可能快的将数据落盘
2019-02-222