程序运行一晚上,早晨一看,出现了Killed信息,然后在网上查找一下,说应该是程序占用资源过高,被系统终止了。
然后我又运行一段时间,看内存果然涨到了使用率40%多,然后就开始查找内存泄漏的问题,由于程序本来就不大,我手动
在代码中找new和malloc,然后又找delete和free,找到了两处,然后修正了。
但是运行一段时间还是在涨,虽然涨的慢了,但是还是有问题,于是就想到了用valgrind。\
第一次使用的时候是用的 valgrind + 程序,这样运行的,但是发现信息好像太少了,于是改成
valgrind --leak-check=full + 程序
这样运行信息就丰富了,但是打印在屏幕上很不方便,于是重定向了输出,
valgrind --leak-check=full 程序名 2> record.txt
2> 是因为valgrind是输出到标准错误上的也就是stderr,文件描述符是2,所以重定向的时候是 2>
这样方便查寻使用。
然后就直接进入文件中,看看有什么问题吧。
==6269== 9 bytes in 1 blocks are possibly lost in loss record 6 of 110 ==6269== at 0x4A069EE: malloc (vg_replace_malloc.c:270) ==6269== by 0x52FF076: sdsnewlen (in /home/xx/workspace/togolden/lib/libDataCache.so) ==6269== by 0x52FC5C9: redisBufferWrite (in /home/xx/workspace/togolden/lib/libDataCache.so) ==6269== by 0x52F9B2C: redisAsyncHandleWrite (in /home/xx/workspace/togolden/lib/libDataCache.so) ==6269== by 0x58A1E0B: event_base_loop (event.c:1350) ==6269== by 0x52CE349: DataCache::Operation::CacheOperation::ExecSubscribe(void*, std::vector<std::string, std::allocator<std::string> > const&) (in /home/xx/workspace/togolden/lib/libDataCache.so) ==6269== by 0x52D2AB9: DataCache::Operation::CacheOperation::Subscribe(DataCache::Operation::Thread*, std::string const&) (in /home/xx/workspace/togolden/lib/libDataCache.so) ==6269== by 0x40463C: CFROMREDIS::run() (in /home/xx/workspace/togolden/bin/GOLDENSCAN.bin) ==6269== by 0x4057A9: main (in /home/xx/workspace/togolden/bin/GOLDENSCAN.bin)
在这个文件里,仔细看,就分几块几块的,其中有下面类似的,以它为开头,下面就是函数逐层的调用过程
==6269== 9 bytes in 1 blocks are possibly lost in loss record 6 of 110
这里用了possibly,是可能会有内存泄漏,其实这种基本上不用管,一般不是这有问题。
==6269== 2,407 (1,824 direct, 583 indirect) bytes in 19 blocks are definitely lost in loss record 103 of 110 ==6269== at 0x4A075BC: operator new(unsigned long) (vg_replace_malloc.c:298) ==6269== by 0x52CA8FC: DataCache::RtDB::CacheRtDB::GetDatas(std::string const&, std::string const&, std::string const&, std::string const&, DataCache::DataModel::CacheMap*) (in /home/xx/workspace/togolden/lib/libDataCache.so) ==6269== by 0x404198: CFROMREDIS::OnMessage(std::string, std::string, std::string) (in /home/xx/workspace/togolden/bin/GOLDENSCAN.bin) ==6269== by 0x52CD0AF: DataCache::Operation::onMessage(redisAsyncContext*, void*, void*) (in /home/xx/workspace/togolden/lib/libDataCache.so) ==6269== by 0x52FA1F1: redisProcessCallbacks (in /home/xx/workspace/togolden/lib/libDataCache.so) ==6269== by 0x58A1E0B: event_base_loop (event.c:1350) ==6269== by 0x52CE349: DataCache::Operation::CacheOperation::ExecSubscribe(void*, std::vector<std::string, std::allocator<std::string> > const&) (in /home/xx/workspace/togolden/lib/libDataCache.so) ==6269== by 0x52D2AB9: DataCache::Operation::CacheOperation::Subscribe(DataCache::Operation::Thread*, std::string const&) (in /home/xx/workspace/togolden/lib/libDataCache.so) ==6269== by 0x40463C: CFROMREDIS::run() (in /home/xx/workspace/togolden/bin/GOLDENSCAN.bin) ==6269== by 0x4057A9: main (in /home/xx/workspace/togolden/bin/GOLDENSCAN.bin)
这一段,其实是内存泄漏的关键,这段信息其实和上面的那个是差不多,唯一不同是这个开头是这么一句
==6269== 2,407 (1,824 direct, 583 indirect) bytes in 19 blocks are definitely lost in loss record 103 of 110
这里用了definitely lost,就是肯定泄漏了这,所以就在这些信息里找带这句的段,然后查看下面的函数调用,是泄漏在哪了,我的这个主要原因是他们给我的库里,我调用他们的存储结构,使用完没有调用他们给定的Destroy操作,虽然定义的时候是比如这样的:CacheValue value;
然后我使用了这个value.GetDatas();其实他内部使用了new,但是我本来是不知道的,其实是还有一个Destroy操作来释放这些new的空间的,修改程序后,问题解决了。
然后说一下快速的使用valgrind的方法,有了前面简单的介绍怎么看问题,那么就说一下简单的方法:
那就是打开这个record.txt文件后,直接使用查找功能,找definitely,这样就可以很快的定位到错误的地方。