linuxfellow
发表于 2015-03-18 23:40
本帖最后由 linuxfellow 于 2015-03-19 00:16 编辑
回复 20# 镇水铁牛
这些还是猜测,以前没有用过,自己没法测试,一切都是纸上谈兵。现在问题的关键就是:
大的message ,从heap分配内存到zmq_msg.content,谁负责free它?zmq_msg_close有没有释放它
凭你的经验,能说说这个指针是如何释放的?
对了,czmq里这个指针是如何释放的?
linuxfellow
发表于 2015-03-18 23:44
本帖最后由 linuxfellow 于 2015-03-18 23:49 编辑
回复 20# 镇水铁牛
给其他部门的建议不能随便提。问题解决不了,提一些让人推倒重来的建议,会遭人鄙视的。无论如何要先解决问题
镇水铁牛
发表于 2015-03-19 00:24
你这样改下,试试看。
while(1)
{
zmq_msg_t zmq_msg;
zmq_msg_init (&zmq_msg);
len = zmq_msg_recv (&zmq_msg, rsock, 0);
if (len >= 0){
zmq_msg_send (&zmq_msg, ssock, 0);//是这里free掉了,你进去看下代码。
} else {
zmq_msg_close (&zmq_msg);
break;
}
}
linuxfellow
发表于 2015-03-20 09:44
本帖最后由 linuxfellow 于 2015-03-20 10:37 编辑
回复 23# 镇水铁牛
问题还没有解决,上面那个还是不行, app认为指针是在zmq_msg_close()里释放:
if (u.base.type == type_lmsg) {
//If the content is not shared, or if it is shared and the reference
//count has dropped to zero, deallocate it.
if (!(u.lmsg.flags & msg_t::shared) ||
!u.lmsg.content->refcnt.sub (1)) {
//We used "placement new" operator to initialize the reference
//counter so we call the destructor explicitly now.
u.lmsg.content->refcnt.~atomic_counter_t ();
if (u.lmsg.content->ffn)
u.lmsg.content->ffn (u.lmsg.content->data,
u.lmsg.content->hint);
free (u.lmsg.content);
}
}
有两个情况下内存不从heap里释放:
u.lmsg.flags & msg_t::shared
u.lmsg.content->refcnt.sub (1) --〉是不是另外一端如果不取。
这两个条件在什么条件下设置?
如果u.lmsg.content->refcnt.sub (1)是真, 另外一端一直不取,zmq_msg_close()返回的时候u.lmsg.content没有被释放。
接着进行下一轮:zmq_msg_init(). u.lmsg.content没有被释放, zmq_msg_init怎么办?
重用u.lmsg.content里的内存,它如何知道subscriber接受过这个信息没有?
申请一块新的内存? 已有的u.lmsg.content里的内存是不是就丢了,造成泄漏?
linuxfellow
发表于 2015-03-20 10:17
回复 23# 镇水铁牛
铁牛兄弟,你把我抬上轿了,我现在还没有下来呀,帮我好好想想上面的问题。
短短的3行代码,有内存泄露,一夜之间heap涨到30兆。多谢了!!!
linuxfellow
发表于 2015-03-20 12:40
本帖最后由 linuxfellow 于 2015-03-20 19:44 编辑
,,,,,,,,,,
镇水铁牛
发表于 2015-03-20 20:07
现在搞定么?基于czmq开发,这些问题都没有了,czmq的代码是能兼容zmq的,没风险。
linuxfellow
发表于 2015-03-20 21:06
回复 27# 镇水铁牛
还有一些问题:
zmq_msg_close (&zmq_msg) 返回时zmq_msg.content没能释放,因为接受端还没有取
这种情况下,下一次循环时,zmq_msg_init 如何处理zmq_msg.content
如果zmq_msg_recv马上又接到一个大的新message, zmq_msg_recv如何处理还没来得及释放的zmq_msg.content?链到一起?会不会抹掉没能释放zmq_msg.content?
发送端调用zmq_msg_close后,zmq_msg.content没能释放,因为接受端还没有取。接受端就得负责释放zmq_msg.content。接受端如何保证释放发送端zmq_msg_close后的zmq_msg.content
镇水铁牛
发表于 2015-03-20 21:29
回复 28# linuxfellow
具体我没有深究,如果有内存泄露,用memcheck检测下,我一直用czmp开发的哈。
linuxfellow
发表于 2015-03-20 21:50
本帖最后由 linuxfellow 于 2015-03-20 22:44 编辑
回复 29# 镇水铁牛
有内存泄露, 一夜之间RSS涨到7357页。不然我不会在这里费劲
root@abc:: dmesg
[ 7785] 07785 17378 7357 0 0 0 zmq
你就当我这些问题是问czmp的, 如果是同样的init/recv/send函数在czmp用,发送端没有来得及释放的zmq.content是如何最终被接收端正确地释放的?
能不能拿czmp的实现来回答一下我上面的问题? 既然czmp和zmq兼容,处理的方法应该差不多