如何使用GLIB结合C语言正确读取INI文件并解决内存泄漏问题
问题根因
你提交的代码本身不存在资源泄漏问题:GKeyFile和GError的释放逻辑覆盖了所有分支,没有遗漏未释放的资源。
valgrind上报的泄漏属于GLib内部的一次性初始化缓存:第一次调用g_key_file_new时会触发国际化相关的语言名称缓存初始化,这块内存由GLib内部管理,不会主动释放,会留存到进程退出。
解决方案
处理当前definitely lost记录
有两种可选处理方式:
- 若你使用的GLib版本≥2.64,在进程退出前调用
g_libstruct_cleanup()函数,可主动释放GLib所有内部缓存的内存 - 低版本GLib可直接使用发行版预装的GLib valgrind忽略规则,过滤这类内部泄漏,避免干扰业务代码问题排查,运行valgrind时添加参数即可:
valgrind --suppressions=/usr/share/glib-2.0/valgrind/glib.supp [你的程序启动参数]
清除Still Reachable记录
Still Reachable记录大多来自GLib的slice分配器缓存、字符串池、类型系统缓存等留存的内存,除了调用上述清理函数外,还可在程序运行前设置如下环境变量,从根源消除这类记录:
export G_SLICE=always-malloc export G_DEBUG=gc-friendly
这两个参数会强制GLib所有内存申请走系统malloc接口、禁用内部缓存,valgrind统计时就不会出现留存的可达内存。
额外优化建议
- 你当前的实现每次调用函数都会重新加载整个INI文件,若调用频率较高会有明显性能损耗,建议增加文件修改时间校验:如果INI文件的mtime没有变化,就复用已经加载完成的
GKeyFile对象,避免重复IO和初始化操作。 - 注意
g_key_file_get_int64返回值为gint64类型,你当前函数返回值为long,在32位环境下long为4字节,会出现8位整数截断问题,建议将函数返回值改为gint64类型避免兼容性风险。
内容的提问来源于stack exchange,提问作者Jonis Maurin Ceará
相关产品推荐
相关产品推荐

