磨砺技术珠矶,践行数据之道,追求卓越价值
回到上一级页面: PostgreSQL集群方案相关索引页     回到顶级页面:PostgreSQL索引页
[作者 高健@博客园  luckyjackgao@gmail.com]

接上文,继续对pgpool-II3.1的内存泄漏进行分析。

情形A extract_string 调用 strdup

==27927== 3 bytes in 1 blocks are possibly lost in loss record 3 of 100
==27927== at 0x4A05E1C: malloc (vg_replace_malloc.c:195)
==27927== by 0x3C51E798C1: strdup (in /lib64/libc-2.5.so)
==27927== by 0x40C9C4: extract_string (pool_config.l:2065)
==27927== by 0x410D52: pool_get_config (pool_config.l:1756)
==27927== by 0x4066B5: main (main.c:320)
==27927==

从上述log可知, 调用关系如下:
main->pool_get_config -> extract_string -> strdup->malloc

以下是各个函数的主要相关逻辑:
pool_get_config函数(中间省略了很多):

int pool_get_config(char *confpath, POOL_CONFIG_CONTEXT context){      ......                                #define PARSE_ERROR()             pool_error("pool_config: parse error at line %d '%s'", Lineno, yytext)                                              /* open config file */                                        fd = fopen(confpath, "r");                                        if (!fd){                                        fprintf(stderr, "pool_config: could not open configuration file (%s)\n", POOL_CONF_FILE_NAME);                            fprintf(stderr, "pool_config: using default values...\n"); return 0;                                    }                                        yyin = fd;                                        Lineno = 1;                                        for(;;)                                        {                                        token = yylex();                                    if (token == 0){                                    break;                                  }                                    if (token == POOL_PARSE_ERROR){                                    PARSE_ERROR();                                fclose(fd);                                return(-1);                                }                                    if (token == POOL_EOL)                                    continue;                                if (token != POOL_KEY){                                    PARSE_ERROR();                                fclose(fd);                                return(-1);                                }                                    ……                                    if (!strcmp(key, "allow_inet_domain_socket") &&              CHECK_CONTEXT(INIT_CONFIG, context)){ ……                                }                                    else if (!strcmp(key, "listen_addresses") &&             CHECK_CONTEXT(INIT_CONFIG, context)){ char *str;                     if (token != POOL_STRING && token != POOL_UNQUOTED_STRING &&                    token != POOL_KEY){                                PARSE_ERROR();                            fclose(fd);                            return(-1);                            }                                str = extract_string(yytext, token);                                if (str == NULL){                                fclose(fd);                            return(-1);                            }                                pool_config->listen_addresses = str;                                }                                    ……                                  else if (!strncmp(key, "backend_hostname", 16) &&CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) && mypid == getpid())                    /* this parameter must be modified by parent pid */                            {                                    int slot;                                char *str;                    slot = atoi(key + 16);                                if (slot < 0 || slot >= MAX_CONNECTION_SLOTS){                                pool_error("pool_config:                      backend number %s for backend_hostname out of range", key);fclose(fd);                            return(-1);                            }                                str = extract_string(yytext, token);                                if (str == NULL){                                fclose(fd);                            return(-1);                            }                                if (context == INIT_CONFIG || (context == RELOAD_CONFIG &&                  BACKEND_INFO(slot).backend_status == CON_UNUSED)) strncpy(BACKEND_INFO(slot).backend_hostname, str,                        MAX_DB_HOST_NAMELEN);                            }                                  ……                                    else if (!strcmp(key, "relcache_expire") &&               CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)){ int v = atoi(yytext);          if (token != POOL_INTEGER || v < 0){                                pool_error("pool_config: %s                      must be equal or higher than 0 numeric value", key);                          fclose(fd);                            return(-1);                            }                                pool_config->relcache_expire = v;                                }                                 }                                        fclose(fd);                            ……                                        return 0;
}                                            

extract_string 函数:

static char *extract_string(char *value, POOL_TOKEN token){                        char *ret;          ret = strdup(value);                    if (!ret){                    pool_error("extract_string: out of memory");                return NULL;                }                    if (token == POOL_STRING){                    ret[strlen(ret)-1] = '\0';                return (ret+1);                }                    return ret;
}

strdup 是C 语言的标准函数, 是字符串复制。
其内部调用了 malloc ,在运行结束的时候,应当释放。

但是!  
由于其 是在 pool_config.c 的 pool_get_config 中被调用,
这个函数 是要实现 把配置文件中的各项内容读取出来。
配置文件项内容的地址,就存储在 strdup 返回的 指针里面。

在pgpool 运行结束以前, 都是需要能随时访问 配置文件向内容的。
所以,在pgpool运行结束以前,都是不能随意 释放 strdup返回 值的。

至于运行结束的那一刻 是否 有代码专门来释放了,前面我们的分析已经说过,不在我们的讨论范围内。

[作者 高健@博客园  luckyjackgao@gmail.com]
回到上一级页面: PostgreSQL集群方案相关索引页     回到顶级页面:PostgreSQL索引页
磨砺技术珠矶,践行数据之道,追求卓越价值

转载于:https://www.cnblogs.com/gaojian/archive/2012/08/21/2649037.html

pgpool-II3.1 的内存泄漏(四)相关推荐

  1. 错误: 内存泄漏,当您使用 GetDC 方法和 ReleaseDC 方法的 CWnd 类版本

    症状 调用CWnd::GetDC函数跟CWnd::ReleaseDC函数的代码运行时,会出现 4 个字节的内存泄漏. 原因 导致此错误的原因是当前未知. 解决方案 若要避免此问题,请不要使用GetDC ...

  2. Handler为什么可能会造成内存泄漏以及可用的四种解决方法

    在Android系统中,Handler是一个消息发送和处理机制的核心组件之一,与之配套的其他主要组件还有Looper和Message,MessageQueue. 根据官网的描述 There are t ...

  3. js内存泄漏常见的四种情况(From LeuisKen)

    本文主要选取了4 Types of Memory Leaks in JavaScript and How to Get Rid Of Them 这篇文章中的一小部分来说明一下js中产生内存泄漏的常见情 ...

  4. [摘译]js内存泄漏常见的四种情况

    本文主要选取了4 Types of Memory Leaks in JavaScript and How to Get Rid Of Them 这篇文章中的一小部分来说明一下js中产生内存泄漏的常见情 ...

  5. JavaScript内存管理机制以及四种常见的内存泄漏解析

    转自:http://geek.csdn.net/news/detail/238898 原文:How JavaScript works: memory management + how to handl ...

  6. android释放acitity内存,Android 内存泄漏分析与解决方法

    在分析Android内存泄漏之前,先了解一下JAVA的一些知识 1. JAVA中的对象的创建 使用new指令生成对象时,堆内存将会为此开辟一份空间存放该对象 垃圾回收器回收非存活的对象,并释放对应的内 ...

  7. 内存溢出和内存泄漏的定义,产生原因以及解决方法(面试经验总结)

    一.定义(概念与区别) 内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory:比如申请 了一个integer,但给它存了long才能存 ...

  8. python会不会出现内存泄露_Python内存泄漏和内存溢出的解决方案

    一.内存泄漏 像Java程序一样,虽然Python本身也有垃圾回收的功能,但是同样也会产生内存泄漏的问题. 对于一个用 python 实现的,长期运行的后台服务进程来说,如果内存持续增长,那么很可能是 ...

  9. Java 内存泄漏排查,新技能+1

    点击关注公众号,Java干货及时送达 来源 | https://zhenbianshu.github.io/ 前些日子小组内安排值班,轮流看顾我们的服务,主要做一些报警邮件处理.Bug 排查.运营 i ...

最新文章

  1. mysql释放练级_面试官:谈谈Mysql事务隔离级别?
  2. JNDI数据源的配置
  3. [leetcode] 117 填充每个节点的下一个右侧节点指针
  4. win7蓝牙怎么连接_台式机蓝牙怎么连接
  5. SQL Server创建数据库和数据的增删改查
  6. Aladdin and the Flying Carpet (素数打表+正整数的唯一分解定理,找因数对)
  7. Junit4中Test Suite的用法
  8. 【转】系统缓存全解析一
  9. AI算力的阿喀琉斯之踵:内存墙
  10. 因为孤浪的关于爱情...关于婚姻...关于生活... 走进的CTO的第一天
  11. Python可视化库Matplotlib的使用
  12. vm怎么装vim_虚拟机中Ubuntu下安装vim及配置文件和插件之菜鸟初体验
  13. 数据库学习入门(转)
  14. postgresql14编译安装参考手册(centos)
  15. 透明网桥(transparent bridge)
  16. python 每天定时运行程序(傻瓜式倒计时)
  17. Linux使用cp命令报cp:omitting directory错误
  18. Eureka源码-double check单例模式运用
  19. 互联网应用:不以抄袭为耻,但以抄袭为常
  20. 讲透学烂二叉树(六):二叉树的笔试题:翻转|宽度|深度

热门文章

  1. 如何使用Tmux提高终端环境下的效率
  2. 如何查看linux系统的体系结构
  3. DDL与DML的区别
  4. VALSE2019总结(2)-以人为中心的视觉理解
  5. 「SDOI2016」储能表(数位dp)
  6. 总结一些java编程题的思路
  7. 20180429 xlVBA套打单据自适应列宽
  8. C#Winform程序如何发布并自动升级(图解)
  9. shell实现简单的进程监控脚本
  10. html5实现进度条功能效果非常和谐