• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

linux下创建线程内存泄漏,php的json_en_php

php 搞代码 7年前 (2018-06-21) 187次浏览 已收录 0个评论

 

这次还是把遇到的几个问题整理一下,希望再遇到的同学能轻松解决。另外最近博客的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);

这样问题就可以解决了。
参考资料:

http://www.gaodaima.com/50290.htmllinux下创建线程内存泄漏,phpjson_en_php

解决了一个隐蔽的内存泄漏——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 
      <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule . http://feed.feedsky.com/vimer [L] </IfModule>

那么当访问 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,最近的总结就这么多~

欢迎大家阅读linux下创建线程内存泄漏,php的json_en_php》,跪求各位点评,若觉得好的话请收藏本文,by 搞代码


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:linux下创建线程内存泄漏,php的json_en_php

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址