问题由来:之前使用的时候一直发现内存占用太高,但是找不到具体问题出现的地方。因为项目使用了一些第三方库(wamp.ws c++, msgpack etc.)。
今天决定好好找一下这个bug,用了一个很无奈的方法,就是根据调用顺序,逐步定位内存增加的代码块。那怎么知道内存在某一个地方增加了呢?看下面这段代码:
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
int parseLine(char* line){
// This assumes that a digit will be found and the line ends in " Kb".
int i = strlen(line);
const char* p = line;
while (*p <'0' || *p > '9') p++;
line[i-3] = '\0';
i = atoi(p);
return i;
}
int getValue(){ //Note: this value is in KB!
FILE* file = fopen("/proc/self/status", "r");
int result = -1;
char line[128];
while (fgets(line, 128, file) != NULL){
if (strncmp(line, "VmSize:", 7) == 0){
result = parseLine(line);
break;
}
}
fclose(file);
return result;
}
直接在 Stack Overflow上复制过来的,没错,就是打印当前进程在该处的内存占用。还有一种方法是直接全局替换 new operator
(see link),但是基于这是模块化的代码(动态库加载),不能全局替换。
定位问题后就好办了,问题好像是由于 boost::promise
和 boost::future
的 bug 引起的,见链接:https://svn.boost.org/trac/boost/ticket/12220
并且由于 boost::future<T>::then(){...}
默认每次都会新建一个线程执行回调,而不是按照顺序执行。在boost的bug描述中,如果采用boost::launch::deferred
调用策略也不会有问题。因此,解决方法就是:
boost::future<T>::then(
boost::launch::deferred,
[&](boost::future<int> reg) {...}
);
修改为 boost::launch::deferred
策略,这样就是在当前线程执行回调函数。
see link:
https://github.com/crossbario/autobahn-cpp/issues/156
http://stackoverflow.com/questions/22934575/why-does-boostfuturetthen-spawn-a-new-thread