68336016 发表于 2018-8-4 13:53:15

有什么工具可以监测到一个函数的内存开销?代码为纯C代码

要将一份代码封装成函数给人调用,由于真机运行环境运行内存十分有限,所以我的函数得尽量节省内存开销。
代码目前在VISUAL C++和GCC上都可以编译运行,通过任务管理器能看到整个进程的内存,但是没法具体得知我这函数自身的内存开销。
试了下VISUAL STUDIO的诊断工具,在我函数里面打上许多断点的话,每个断点抓一次内存快照,能看得到内存变化,但是很笨,也没法判断函数运行时占用内存最大的是什么时候,具体占用多少。

dr2001 发表于 2018-8-4 14:01:53

本帖最后由 dr2001 于 2018-8-4 14:02 编辑

没有用到C99还是C11的那个什么变长数组之类的特例,对C来说,一般情况下每个函数的栈开销是编译期确定的,有的编译器能输出栈使用情况,比如GCC有个stack-usage的参数。

如果没有使用函数指针、递归等等函数调用方法/特例,那么,整个代码的调用树就是静态可分析的,有的编译器是可以输出调用树的,GCC好像有个call-graph的参数。

Keil的C51的变量分配就是静态调用树分析并且静态分配。

malloc这种运行时内存分配就没办法预先知道了。

68336016 发表于 2018-8-4 14:09:15

dr2001 发表于 2018-8-4 14:01
没有用到C99还是C11的那个什么变长数组之类的特例,对C来说,一般情况下每个函数的栈开销是编译期确定的, ...

这是一个图像处理函数,里面有不少malloc操作,所以我要输入一张图片,想实时监测函数处理过程中的内存开销。

wye11083 发表于 2018-8-4 14:49:48

68336016 发表于 2018-8-4 14:09
这是一个图像处理函数,里面有不少malloc操作,所以我要输入一张图片,想实时监测函数处理过程中的内存开 ...

你不如预分配一些固定大小的块。

mcu5i51 发表于 2018-8-4 14:57:23

动态的自己弄个记数变量,申请时加上,释放时减去;
加上静态的就可以了

dr2001 发表于 2018-8-4 17:37:06

68336016 发表于 2018-8-4 14:09
这是一个图像处理函数,里面有不少malloc操作,所以我要输入一张图片,想实时监测函数处理过程中的内存开 ...

对于需要长期、连续运行的程序,动态内存分配器是需要小心对待的东西。

条件许可的话,能不用就不用,尤其库。缓存让调用者管理。

68336016 发表于 2018-8-4 18:05:35

dr2001 发表于 2018-8-4 17:37
对于需要长期、连续运行的程序,动态内存分配器是需要小心对待的东西。

条件许可的话,能不用就不用,尤 ...

我的函数没有内存泄漏,这肯定要测试过的,就是没法算出最大内存开销。

dr2001 发表于 2018-8-4 18:37:00

68336016 发表于 2018-8-4 18:05
我的函数没有内存泄漏,这肯定要测试过的,就是没法算出最大内存开销。 ...

内存碎片
除非能确定性的达成隔一段时间内存能全部释放


内存泄露是bug,应消除;内存碎片是feature,有风险。

redroof 发表于 2018-8-4 18:53:19

68336016 发表于 2018-8-4 18:05
我的函数没有内存泄漏,这肯定要测试过的,就是没法算出最大内存开销。 ...

自己封装一层特殊的malloc就行了,自己记住分配岀来的总数。
除非你还用到了一些间接调用malloc的库函数,导致无法调用到你封装的malloc
那么就只能去替换你的编译器里面的那个malloc了,各家编译器的做法都不同,但是肯定有办法替换

wudicgi 发表于 2018-8-4 19:06:06

以前没研究过这方面内容,不知道 LZ 的程序是所有源码都是自己编译的,还是有一部分用的现成的二进制库
可以 Google 搜索一下 malloc statistics, 有类似 malloc_stats(), malloc_zone_statistics() 这样的函数,也许可以用

Ray______ 发表于 2018-8-4 22:36:50

我也同意9楼的封装MALLOC,给接口给调用者注册,调用者去实现这个管理和分析

68336016 发表于 2018-8-4 23:08:57

Ray______ 发表于 2018-8-4 22:36
我也同意9楼的封装MALLOC,给接口给调用者注册,调用者去实现这个管理和分析 ...

按9楼的思路,malloc开辟了多少是能计算出来的,将每次开辟的大小累计起来得到一个值。
如果中间有释放的,暂时没想到办法计算,free函数释放操作得不到空间的长度。

redroof 发表于 2018-8-5 11:52:14

68336016 发表于 2018-8-4 23:08
按9楼的思路,malloc开辟了多少是能计算出来的,将每次开辟的大小累计起来得到一个值。
如果中间有释放的 ...

malloc自己的记录信息里面是有的。如果你得不到,也可以自己记一份:比如正常要分配100字节,你的特殊malloc实际分配104字节,前面记下长度,然后偏移4个字节再送给程序。程序free的时候,你也造个特殊的free就行了,按前面自己记的长度减掉,再调用正常free

68336016 发表于 2018-8-5 12:34:20

本帖最后由 68336016 于 2018-8-5 12:35 编辑

redroof 发表于 2018-8-5 11:52
malloc自己的记录信息里面是有的。如果你得不到,也可以自己记一份:比如正常要分配100字节,你的特殊mall ...

{:lol:} 好思路,前面几个字节记录下开辟的长度,然后free时候再查询下这长度就知道这次释放要减去多少字节了。

不过这种多行宏定义,在GCC上还好,在VC上,各种不兼容

redroof 发表于 2018-8-5 12:46:09

68336016 发表于 2018-8-5 12:34
好思路,前面几个字节记录下开辟的长度,然后free时候再查询下这长度就知道这次释放要减去多少字 ...

做个函数就行,define只是把正常的malloc和free变成你做的那一份
只要不是必须替换系统的那个malloc,别的没难度。非得替换系统malloc的场合关键是兼容性,没有标准的方法去替换系统malloc,每个编译器都有自己的做法

cloudboy 发表于 2018-8-6 09:36:29

既然是malloc,应该相对容易统计最大开销的吧,程序规模很大?

shian0551 发表于 2018-8-6 11:02:14

有内存泄漏测试,没有检测内存使用。哥们服你了

68336016 发表于 2018-8-6 12:52:22

shian0551 发表于 2018-8-6 11:02
有内存泄漏测试,没有检测内存使用。哥们服你了

内存泄露测试就简单,vs2015里面几个函数添加下就行了。
而内存开销一般情况也没必要做,也就这次设备资源实在有限,才需要测下。
这种估计也有现成工具可以做到的,在调用别人的库时候,没代码,一个个地方去累计就行不通。

redroof 发表于 2018-8-6 15:07:42

68336016 发表于 2018-8-6 12:52
内存泄露测试就简单,vs2015里面几个函数添加下就行了。
而内存开销一般情况也没必要做,也就这次设备资 ...

没代码那么就是替换编译器内置的malloc啊
GCC的标准做法是malloc hooks
VC的标准做法是 _CrtSetAllocHook


页: [1]
查看完整版本: 有什么工具可以监测到一个函数的内存开销?代码为纯C代码