You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

海思3516EV200平台嵌入式Linux程序内存异常波动排查求助

排查内存异常波动的思路和问题点

首先,从你描述的内存变化规律(缓慢下降→快速回升→循环)来看,这更可能是内核层面的内存回收/页缓存释放行为,而非用户态程序的内存泄漏——毕竟典型的内存泄漏是持续增长不会回落的。不过咱们还是结合你的代码和环境一步步排查:

一、先修复代码里的明显资源泄漏问题

你的代码里有几个容易引发资源占用的问题,先把这些坑填上:

  1. 错误分支的socket未关闭
    local_inet调用失败时,你直接写了return NULL;,但mainvoid类型,这个返回本身就不合法;更关键的是,此时已经创建的sockfd没有调用close()关闭,会导致文件描述符泄漏,累积下来会占用系统资源,间接影响内存使用。
    修复方式:

    if (0 != ret){
        printf("get local ip failed");
        close(sockfd); // 新增:关闭已创建的socket
        return; // main是void类型,不要return NULL
    }
    
  2. TCP keepalive配置的潜在风险
    你调用了set_tcp_keep_alive(sockfd),但不清楚这个函数的具体实现。如果keepalive参数配置不合理(比如探测间隔过短、重试次数过多),可能会导致TCP连接断开后残留内核态的连接资源,这些资源会在一定时间后被内核回收,这可能是内存快速回升的诱因。建议检查这个函数的实现,尽量贴合内核默认的合理参数(比如tcp_keepidle=7200tcp_keepintvl=75tcp_keepcnt=9)。

二、分析内存波动的核心原因:内核页缓存的影响

你用free命令监测的内存数值,包含了内核的页缓存(Cached)部分。嵌入式系统中,当程序持续进行网络IO(比如你的程序每隔5秒发送数据),内核会用空闲内存缓存网络数据、文件数据等,导致free显示的空闲内存缓慢下降;当内核检测到空闲内存不足时,会主动回收这些页缓存,释放内存,这就会出现你看到的快速回升到22M的现象。

验证这个猜测的方法:

  • cat /proc/meminfo查看更详细的内存统计,重点关注CachedBuffersMemFree这几个字段的变化:如果MemFree下降的同时Cached在上升,内存回升时Cached大幅下降,那基本可以确定是页缓存的正常回收。
  • 手动触发页缓存回收验证:执行echo 3 > /proc/sys/vm/drop_caches,如果内存立刻回升到接近初始值,就能确认是页缓存导致的波动。

三、如果确实怀疑内存泄漏的排查方法

如果排除了页缓存的因素,想要确认是否存在用户态内存泄漏,可以试试这些方法:

  • mtrace工具:编译程序时加上-g-lmcheck选项,运行程序后生成内存跟踪日志,分析是否有未释放的内存。
  • 自定义内存统计:在程序中对动态分配的内存(比如malloc/free)做计数,打印每次分配和释放的大小,跟踪内存变化。
  • valgrind(限资源充足的环境):如果开发板资源足够,或者能在交叉编译主机环境模拟运行,可以用valgrind --leak-check=full ./your_program检查泄漏点。

内容的提问来源于stack exchange,提问作者zssheng zss

火山引擎 最新活动