技术头条 - 一个快速在微博传播文章的方式     搜索本站
您现在的位置首页 --> 其他 --> 最近遇到的问题整理(linux下创建线程内存泄漏,php的json_encode等)

最近遇到的问题整理(linux下创建线程内存泄漏,php的json_encode等)

浏览:2305次  出处信息

    这次还是把遇到的几个问题整理一下,希望再遇到的同学能轻松解决。另外最近博客的feeds延迟更新的原因也会一起说明一下。

    1.linux下创建线程导致内存泄漏

     今天在外网发布了一个server之后,用top发现virt的使用量一直在涨,而且一次涨8m。于是可以断定有内存泄漏了,经过排查,最终确定原因出在多线程的问题上:

     代码如下:

1
2
3
4
5
6
pthread_t thread_id;
int ret=pthread_create(&thread_id, NULL, flush_thread_work, (void*)&m_sql_client);
if(ret!=0){
    APPSCORE_ERROR("Thread creation failed:%d",ret);
    return ret;
}

    在flush_thread_work函数内部:

1
2
3
4
5
void* flush_thread_work(void* args)
{
    //....do something
    return NULL;
}

    代码中启动了一个线程之后,主进程就继续执行,任由新线程自生自灭了(没有调用thread_join),而主进程每隔一段时间就会拉起这样一个线程来做一些数据落地的事情。

    这样的写法实际上是会造成内存泄漏的.

     Linux man page 里有已经说明了这个问题:

     When a joinable thread terminates, its memory resources (thread descriptor and stack) are not deallocated until another thread performs pthread_join on it. Therefore, pthread_join must be called once for each joinable thread created to avoid memory leaks.

    也就说线程执行完后如果不join的话,线程的资源会一直得不到释放而导致内存泄漏!

    解决方法有两种:

     a.在线程执行的函数内手工释放

1
2
3
4
5
6
void* flush_thread_work(void* args)
{
    //....do something
    pthread_detach(pthread_self());
    return NULL;
}

    b.在线程启动时,设置线程的PTHREAD_CREATE_DETACHED属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
pthread_attr_t attr;
pthread_attr_init (&attr);
pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
 
int ret=pthread_create(&thread_id, &attr, flush_thread_work, (void*)&m_sql_client);
if(ret!=0){
    //记住attr也要析构,否则又是一个内存泄漏
    pthread_attr_destroy (&attr);
    APPSCORE_ERROR("Thread creation failed:%d",ret);
    return ret;
} 
 
//记住attr也要析构,否则又是一个内存泄漏
pthread_attr_destroy (&attr);

    这样问题就可以解决了。

     参考资料:

     解决了一个隐蔽的内存泄漏――pthread_create后没有detach导致内存持续增长

    2.php的json_encode函数问题

     在公司做了一个应用,是php与c++进行网络交互,所以选择了json这种比较通用的序列化格式,然而却遇到了比较奇怪的问题。

     先来看如下代码(php):

1
2
3
4
5
$objs = array();
$objs[1] = \'a\';
$objs[2] = \'b\';
$objs[4] = \'d\';
echo json_encode($objs)."\\n";

    输出的结果如下:

{"0":"a","1":"b","3":"d"}

    这样是正常的,用jsoncpp也可以正确的解析出来,php自动将$objs当作一个关联数组来生成json数据了。

     然而当把代码换成如下:

1
2
3
4
5
6
$objs = array();
$objs[0] = \'a\';
$objs[1] = \'b\';
$objs[2] = \'c\';
$objs[3] = \'d\';
echo json_encode($objs)."\\n";

    则输出结果如下:

["a","b","c","d"]

    jsoncpp按照之前的解析方法是解析不出来的~

     其实对php来说,这也是合理的,问题在于在php里面普通数组和关联数组都是array,而对c++来说,却存在vector和map之分,所以如果还是想要json_encode生成关联数组的格式,那么需要这样写:

1
2
3
4
5
6
$objs = array();
$objs[0] = \'a\';
$objs[1] = \'b\';
$objs[2] = \'c\';
$objs[3] = \'d\';
echo json_encode((object)$objs)."\\n";

    结果如下:

{"0":"a","1":"b","2":"c","3":"d"}

    3.本博feed延迟不更新的原因

     之前由于对feedsky的feed更新十分不满,所以参考网上的做法,建立了一个feed.vimer.cn,而本博所在的域名空间会自动根据域名创建一个子目录 - feed,修改这个目录下的.htaccess文件如下:

1
2
3
4
5

RewriteEngine On
RewriteBase /
RewriteRule . http://feed.feedsky.com/vimer [L]

    那么当访问 feed.vimer.cn 时,会自动跳转到 http://feed.feedsky.com/vimer

     然而我忽略了一个问题,那就是wordpress默认的feed链接是 http://vimer.cn/feed/rss2,而/feed/rss2会被解析成子目录,从而自动跳转到 http://feed.feedsky.com/vimer ,所以feedsky就会不停的读 http://feed.feedsky.com/vimer 这个链接的feed,当然不会有任何新数据。。

    所以最后还是把这种方式废弃掉了,看来真是冤枉了feedsky呀~~~

    OK,最近的总结就这么多~

建议继续学习:

  1. iOS内存暴增问题追查与使用陷阱    (阅读:4351)
  2. 为什么重复free()比内存泄漏危害更大    (阅读:3045)
  3. 在回调和闭包中的内存泄漏    (阅读:3100)
  4. json_encode数组出现unicode \uxxxx的解决方案    (阅读:2716)
  5. Linux C/C++ 内存泄漏检测工具:Valgrind    (阅读:2266)
  6. 如何让 PHP json_encode 函数不转义中文?    (阅读:1337)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
© 2009 - 2024 by blogread.cn 微博:@IT技术博客大学习

京ICP备15002552号-1