cgo内存泄漏排查

示例程序:

package main/*
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
char* cMalloc() {char *mem = (char*)malloc(1024 * 1024 * 16);return mem;
}
void cMemset(char* mem) {memset(mem, '-', 1024 * 1024 * 16);
}
int arrLen = 1000;
int arrIndex;
char* globalMemAddr[1000];
void printAddr(char* mem) {if (arrIndex+1 >= arrLen) {arrIndex = 0;} else {arrIndex++;}globalMemAddr[arrIndex] = mem;printf("index: %d, addr: %p\n", arrIndex, globalMemAddr[arrIndex]);
}
*/
import "C"
import ("fmt""net/http"_ "net/http/pprof""os""runtime""sync""time""unsafe"
)var size int = 1024 * 1024 * 16
var memStat runtime.MemStatsfunc main() {go func() {_ = http.ListenAndServe("0.0.0.0:9091", nil)}()if len(os.Args) > 1 && os.Args[1] == "1" {var wg sync.WaitGroupfor {wg.Add(1)runtime.ReadMemStats(&memStat)fmt.Printf("total memory begin: %v mb\n", memStat.TotalAlloc/1024/1024)go doCMalloc(&wg)wg.Wait()runtime.ReadMemStats(&memStat)fmt.Printf("total memory   end: %v mb\n", memStat.TotalAlloc/1024/1024)time.Sleep(2000 * time.Millisecond)}} else {var wg sync.WaitGroupfor {wg.Add(1)go doGoMalloc(&wg)wg.Wait()time.Sleep(2000 * time.Millisecond)}}
}// 无泄漏
func doCMalloc(wg *sync.WaitGroup) {defer wg.Done()cptr := C.cMalloc()C.cMemset(cptr)C.printAddr(cptr)bs := C.GoBytes(unsafe.Pointer(cptr), C.int(size))fmt.Printf("1: %s .. %s\n", string(bs[0:8]), string(bs[size-8:size]))C.free(unsafe.Pointer(cptr))
}// 无泄漏
func doGoMalloc(wg *sync.WaitGroup) {defer wg.Done()bs := make([]byte, size, size)cptr := (*C.char)(unsafe.Pointer(&bs[0]))C.cMemset(cptr)C.printAddr(cptr)fmt.Printf("2: %s .. %s\n", string(bs[0:8]), string(bs[size-8:size]))
}

运行分支1:

将doCMalloc函数内的C.free注释掉。

go build memleak.go
./memleak 1

查看控制台输出:

查看top输出:

查看pprof输出:

#yum install graphvizgo tool pprof -http=192.168.36.5:9000 http://127.0.0.1:9091/debug/pprof/allocs

常规go工具链无法监测cgo内存:

top显示进程占用1.7g,inuse_space显示占用16mb,runtime.ReadMemStats显示分配过1442mb,alloc_space显示doCMalloc函数分配过944mb。

可以发现:不管是runtime.ReadMemStats还是pprof都不包含cgo内通过c语言分配的内存的占用情况,不能反映真实的进程占用内存情况。

内存泄漏检测之valgrind

centos8安装:

yum install valgrind --nogpgcheck

执行泄漏检测:

将doCMalloc函数内的C.free注释掉。

将代码中的arrLen调小便于出现泄漏,如调成10。

valgrind --tool=memcheck --leak-check=full --error-limit=no --trace-children=yes --show-leak-kinds=all --track-origins=yes --log-file=./log.txt ./memleak 1

检测结果:

给出了泄漏位置:at 0x4C38185: malloc (vg_replace_malloc.c:442)

内存泄漏检测之bcc/tools/memleak

centos8(kernel:4.18.0)安装:

(centos7不支持,需要自己升级内核到4.x版本)

bcc/INSTALL.md at master · iovisor/bcc · GitHub

yum install bcc-tools --nogpgcheck

执行泄漏检测:

将doCMalloc函数内的C.free注释掉。

将代码中的arrLen调小便于出现泄漏,如调成10。

/usr/share/bcc/tools/memleak -a -p `pidof memleak`

对于golang来说如果从程序一启动就执行监测,效果不理想,因为top10可能都是golang正常管理的内存,需要等到所有运行需要的golang管理的内存都预热到go的三级cache中,此时golang很少需要向系统申请内存了,再监测cgo的内存泄漏。

如从启动开始监测:

最好在golang稳定运行后再开始监测,如:

清晰的定位到泄漏位置:0x00007faa43885a71      sysmalloc+0x7d1 [libc-2.28.so]

还可以指定监测最小的内存泄漏单位(byte),如我们监测大于等于16MB的泄漏:

/usr/share/bcc/tools/memleak --min-size 16777216 -a -p `pidof memleak`

恢复doCMalloc函数内的C.free,再执行监测:

未发现泄漏。

内存泄漏检测之strace

strace只能通过肉眼观察分配和回收是否配对出现或者由于缓存机制不再频繁申请内存,本身不能给出泄漏报告。

执行泄漏检测:

将doCMalloc函数内的C.free注释掉。

将代码中的arrLen调小便于出现泄漏,如调成10。

strace -e 'trace=brk,mmap,munmap' -f -p `ps aux | grep memleak | grep -v 'grep' | awk '{print $2}'`

泄漏情况观察如图:

未泄漏情况观察:

恢复doCMalloc函数内的C.free。

从启动时开始监测:

strace -e 'trace=brk,mmap,munmap' -f ./memleak 1 &> slog &
tail -f slog

显示16mb+的空间分配或映射只在程序启动不久时出现了,之后再没有出现。

--end--

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/61896.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Django的介绍

Django是一个高级的Python Web框架,用于快速开发安全、可维护的Web应用程序。以下是关于Django的详细介绍: 一、框架特点 高效的开发模式 内置功能丰富:Django提供了大量的内置工具和功能,减少了开发人员在构建Web应用基础部分所花费的时间。例如,它自带了一个功能强大的…

第四届新生程序设计竞赛正式赛(C语言)

A: HNUCM的学习达人 SQ同学是HNUCM的学习达人&#xff0c;据说他每七天就能够看完一本书&#xff0c;每天看七分之一本书&#xff0c;而且他喜欢看完一本书之后再看另外一本。 现在请你编写一个程序&#xff0c;统计在指定天数中&#xff0c;SQ同学看完了多少本完整的书&#x…

红日靶场vulnstack (五)

前言 好久没打靶机了&#xff0c;今天有空搞了个玩一下&#xff0c;红日5比前面的都简单。 靶机环境 win7&#xff1a;192.168.80.150(外)、192.168.138.136(内) winserver28&#xff08;DC&#xff09;&#xff1a;192.168.138.138 环境搭建就不说了&#xff0c;和之前写…

汇编语言简要记录-1

汇编语言与汇编指令 汇编语言的主题是汇编指令 汇编指令与机器指令的差别在于指令的表示方法上 1、汇编指令是机器机器指令便于记忆的书写格式 2、汇编指令是机器指令的助记符 ag&#xff1a;机器指令 1000100111011000操作&#xff1a;将寄存器BX的值送到AX中汇编指令 MOV …

C++中实现多态有几种方式

一&#xff09;虚函数&#xff08;Virtual Functions&#xff09;实现多态 概念&#xff1a; 虚函数是在基类中使用关键字virtual声明的成员函数。当一个类包含虚函数时&#xff0c;编译器会为该类创建一个虚函数表&#xff08;v - table&#xff09;&#xff0c;这个表存储了虚…

汽车IVI中控开发入门及进阶(三十七):基于HFP协议的蓝牙电话

概述: HFP全称Hands-free Profile,是一款让蓝牙设备控制电话的软件,多用于汽车上。此类设备最常见的例子是车载免提装置与蜂窝电话或可穿戴无线耳机一起使用。该配置文件定义了支持免提配置文件的两个设备如何在点对点的基础上相互交互。免提模式的实现通常使耳机或嵌入式免…

线程条件变量 生产者消费者模型 Linux环境 C语言实现

只能用来解决同步问题&#xff0c;且不能独立使用&#xff0c;必须配合互斥锁一起用 头文件&#xff1a;#include <pthread.h> 类型&#xff1a;pthread_cond_t PTHREAD_COND_INITIALIZER 初始化 初始化&#xff1a;int pthread_cond_init(pthread_cond_t * cond, NULL);…

AI技术在电商行业中的应用与发展

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

高通---Camera调试流程及常见问题分析

文章目录 一、概述二、Camera配置的整体流程三、Camera的代码架构图四、Camera数据流的传递五、camera debug FAQ 一、概述 在调试camera过程中&#xff0c;经常会遇到各种状况&#xff0c;本篇文章对camera调试的流程进行梳理。对常见问题的提供一些解题思路。 二、Camera配…

高危端口汇总(Summary of High-Risk Ports)

高危端口汇总 能关闭就关闭 &#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解…

贪心算法实例-问题分析(C++)

贪心算法实例-问题分析 饼干分配问题 有一群孩子和一堆饼干&#xff0c;每个小孩都有一个饥饿度&#xff0c;每个饼干都有一个能量值&#xff0c;当饼干的能量值大于等于小孩的饥饿度时&#xff0c;小孩可以吃饱&#xff0c;求解最多有多少个孩子可以吃饱?(注:每个小孩只能吃…

图像处理网络中的模型水印

论文信息&#xff1a;Jie Zhang、Han Fang、Weiming Zhang、Wenbo Zhou、Hao Cui、Hao Cui、Nenghai Yu&#xff1a;Model Watermarking for Image Processing Networks 本文首次提出了图像处理网络中深度水印问题&#xff0c;将知识产权问题引入图像处理模型 提出了第一个深…

【后端面试总结】缓存策略选择

一般来说我们常见的缓存策略有三种&#xff0c;他们各自的优劣势和实现逻辑分别如下 Cache Aside&#xff08;旁路缓存&#xff09; 特点&#xff1a; 灵活性高&#xff1a;应用程序直接与缓存和数据库交互&#xff0c;具有高度的灵活性&#xff0c;可以根据业务需求自定义缓…

【网络安全】网站常见安全漏洞 - 网站基本组成及漏洞定义

文章目录 引言1. 一个网站的基本构成2. 一些我们经常听到的安全事件3. 网站攻击者及其意图3.1 网站攻击者的类型3.2 攻击者的意图 4. 漏洞的分类4.1 按来源分类4.2 按危害分类4.3 常见漏洞与OWASP Top 10 引言 在当今的数字化时代&#xff0c;安全问题已成为技术领域不可忽视的…

spaCy 入门与实战:强大的自然语言处理库

spaCy 入门与实战&#xff1a;强大的自然语言处理库 spaCy 是一个现代化、工业级的自然语言处理&#xff08;NLP&#xff09;库&#xff0c;以高效、易用和功能丰富著称。它被广泛应用于文本处理、信息提取和机器学习任务中。本文将介绍 spaCy 的核心功能&#xff0c;并通过一…

Ubuntu22.04系统源码编译OpenCV 4.10.0(包含opencv_contrib)

因项目需要使用不同版本的OpenCV&#xff0c;而本地的Ubuntu22.04系统装了ROS2自带OpenCV 4.5.4的版本&#xff0c;于是编译一个OpenCV 4.10.0&#xff08;带opencv_contrib&#xff09;版本&#xff0c;给特定的项目使用&#xff0c;这就不用换个设备后重新安装OpenCV 了&…

代码随想录第36天

01背包问题 二维 def hanshu():wupin, bagweight [int(x) for x in input().split()]weight [int(x) for x in input().split()]value [int(x) for x in input().split()]dp [[0]*(bagweight1) for i in range(wupin)] #dp[i][j]代表从物品【0,i-1】让任意取&#xff0c…

[C#]使用 .NET 8/9 中的 Async/Await 避免常见错误并提高性能

在.NET 8中,异步编程对于构建响应迅速且高效的应用程序至关重要。如果使用得当,async/await关键字能够简化异步代码的复杂性,但它也并非毫无挑战。在本文中,我们将探讨开发人员常犯的错误以及避免这些错误的实用策略,所有内容都将基于实际的编码场景展开。让我们深入了解如…

Dataset用load_dataset读图片和对应的caption的一个坑

代码&#xff1a; data_files {} if args.train_data_dir is not None:data_files["train"] os.path.join(args.train_data_dir, "**")dataset load_dataset("imagefolder",data_filesdata_files,cache_dirargs.cache_dir,) 数据&#xff1…

word如何快速创建目录?

文章目录 1&#xff0c;先自己写出目录的各级标题。2、选中目标标题&#xff0c;然后给它们编号3、给标题按照个人需求开始分级4、插入域构建目录。4.1、利用快捷键插入域构建目录4.2、手动插入域构建目录 听懂掌声&#xff01;学会了吗&#xff1f; 前提声明&#xff1a;我在此…