内存管理:内存泄漏分析

内存管理:内存泄漏分析

本文采用知识共享署名 4.0 国际许可协议进行许可,转载时请注明原文链接,图片在使用时请保留全部内容,可适当缩放并在引用处附上图片所在的文章链接。

内存泄漏

在计算机科学中,内存泄漏指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,导致在释放该段内存之前就失去了对该段内存的控制,从而造成了内存的浪费。

Valgrind

编译valgrind

下载 valgrind

wget http://www.valgrind.org/downloads/valgrind-3.14.0.tar.bz2
tar -jxvf valgrind-3.14.0.tar.bz2 

配置工具链

export CC=/usr/local/aarch64-himix100-linux-toolchain-libra-v3/bin/aarch64-himix100-linux-gcc
export AR=/usr/local/aarch64-himix100-linux-toolchain-libra-v3/bin/aarch64-himix100-linux-ar
export LD=/usr/local/aarch64-himix100-linux-toolchain-libra-v3/bin/aarch64-himix100-linux-ld

编译

cd valgrind-3.14.0
./config --host=aarch64-himix100-linux    --prefix=/mnt/DG/DATA/software/valgrind/   --enable-only64bit 
make
make install

使用valgrind

Valgrind的手册 : http://valgrind.org/docs/manual/manual.html

工具选项

–tool= 运行 valgrind中名为toolname的工具。默认memcheck。

  • ​ memcheck ------> 这是valgrind应用最广泛的工具,一个重量级的内存检查器,能够发现开发中绝大多数内存错误使用情况,比如:使用未初始化的内存,使用已经释放了的内存,内存访问越界等。

  • ​ callgrind ------> 它主要用来检查程序中函数调用过程中出现的问题。

  • ​ cachegrind ------> 它主要用来检查程序中缓存使用出现的问题。

  • ​ helgrind ------> 它主要用来检查多线程程序中出现的竞争问题。

  • ​ massif ------> 它主要用来检查程序中堆栈使用中出现的问题。

  • ​ extension ------> 可以利用core提供的功能,自己编写特定的内存调试工具

适用于Memcheck工具的相关选项

–leak-check=no|summary|full 要求对leak给出详细信息? [summary]

–leak-resolution=low|med|high how much bt merging in leak check [low]

–show-reachable=no|yes show reachable blocks in leak check? [no]

LOG信息输出

-xml=yes 将信息以xml格式输出,只有memcheck可用
-num-callers= show callers in stack traces [12]
-error-limit=no|yes 如果太多错误,则停止显示新错误? [yes]
-error-exitcode= 如果发现错误则返回错误代码 [0=disable]
-db-attach=no|yes 当出现错误,valgrind会自动启动调试器gdb。[no]
-db-command= 启动调试器的命令行选项[gdb -nw %f %p]

其他

-h –help 显示帮助信息。
-version 显示valgrind内核的版本,每个工具都有各自的版本。
-q –quiet 安静地运行,只打印错误信息。
-v –verbose 更详细的信息, 增加错误数统计。
-trace-children=no|yes 跟踪子线程? [no]
-track-fds=no|yes 跟踪打开的文件描述?[no]
-time-stamp=no|yes 增加时间戳到LOG信息? [no]
-log-fd= 输出LOG到描述符文件 [2=stderr]
-log-file= 将输出的信息写入到filename.PID的文件里,PID是运行程序的进行ID
-log-file-exactly= 输出LOG信息到 file
-log-file-qualifier= 取得环境变量的值来做为输出信息的文件名。 [none]
-log-socket=ipaddr:port 输出LOG到socket ,ipaddr:port

最常用的命令格式

 valgrind --log-file=valgrind_log --tool=memcheck --leak-check=full --show-leak-kinds=all ./T3RMultimediaTest

valgrind 输出分析

==1797== Memcheck, a memory error detector
==1797== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==1797== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==1797== Command: ./T3RMultimediaTest
==1797== Parent PID: 1794
==1797== 
==1797== Warning: noted but unhandled ioctl 0x501b with no size/direction hints.
==1797==    This could cause spurious value errors to appear.
==1797==    See README_MISSING_SYSCALL_OR_IOCTL for guidance on writing a proper wrapper.
==1797== Thread 18:
==1797== Syscall param ioctl(generic) points to unaddressable byte(s)
==1797==    at 0x7F9E0FC: ioctl (ioctl.S:26)
==1797==    by 0x5617C2F: vcodec_service_init (vcodec_service.c:214)
==1797==    by 0x5616527: mpp_dev_init (mpp_device.c:86)
==1797==    by 0x55CA5EB: hal_h264e_vepu2_init_v2 (hal_h264e_vepu2_v2.c:115)
==1797==    by 0x55C522F: hal_h264e_init (hal_h264e_api_v2.c:76)
==1797==    by 0x54F815B: mpp_enc_hal_init (mpp_enc_hal.cpp:78)
==1797==    by 0x54F0EC7: mpp_enc_init_v2 (mpp_enc_v2.cpp:1505)
==1797==    by 0x54E7ADB: Mpp::init(MppCtxType, MppCodingType) (mpp.cpp:182)
==1797==    by 0x54EB453: mpp_init (mpi.cpp:489)
==1797==    by 0x59E20E3: vega::rknn::Venc::creatVenc(int, int, int, int, int) (in /home/toybrick/Rockchip/zyh/t3r_pressure_test/T3RHeadDetectTest/release/aarch64-rk3399pro-linux/lib/libvega.so)
==1797==    by 0x59E2DDB: vega::rknn::Venc::creatVideoVenc(unsigned long long, int, int, int, int, float, int, int, std::function<void (unsigned long long, std::shared_ptr<vega::Matrix>, DgError)>) (in /home/toybrick/Rockchip/zyh/t3r_pressure_test/T3RHeadDetectTest/release/aarch64-rk3399pro-linux/lib/libvega.so)
==1797==    by 0x59DF007: vega::rknn::RknnMM::createVenc(unsigned long long, vega::MatrixType, vega::MatrixType, cv::Size_<int> const&, int, int, float, int, int, std::function<void (unsigned long long, std::shared_ptr<vega::Matrix>, DgError)>) (in /home/toybrick/Rockchip/zyh/t3r_pressure_test/T3RHeadDetectTest/release/aarch64-rk3399pro-linux/lib/libvega.so)
==1797==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==1797== 
==1797== Syscall param ioctl(generic) points to unaddressable byte(s)
==1797==    at 0x7F9E0FC: ioctl (ioctl.S:26)
==1797==    by 0x5617C67: vcodec_service_init (vcodec_service.c:218)
==1797==    by 0x5616527: mpp_dev_init (mpp_device.c:86)
==1797==    by 0x55CA5EB: hal_h264e_vepu2_init_v2 (hal_h264e_vepu2_v2.c:115)
==1797==    by 0x55C522F: hal_h264e_init (hal_h264e_api_v2.c:76)
==1797==    by 0x54F815B: mpp_enc_hal_init (mpp_enc_hal.cpp:78)
==1797==    by 0x54F0EC7: mpp_enc_init_v2 (mpp_enc_v2.cpp:1505)
==1797==    by 0x54E7ADB: Mpp::init(MppCtxType, MppCodingType) (mpp.cpp:182)
==1797==    by 0x54EB453: mpp_init (mpi.cpp:489)
==1797==    by 0x59E20E3: vega::rknn::Venc::creatVenc(int, int, int, int, int) (in /home/toybrick/Rockchip/zyh/t3r_pressure_test/T3RHeadDetectTest/release/aarch64-rk3399pro-linux/lib/libvega.so)
==1797==    by 0x59E2DDB: vega::rknn::Venc::creatVideoVenc(unsigned long long, int, int, int, int, float, int, int, std::function<void (unsigned long long, std::shared_ptr<vega::Matrix>, DgError)>) (in /home/toybrick/Rockchip/zyh/t3r_pressure_test/T3RHeadDetectTest/release/aarch64-rk3399pro-linux/lib/libvega.so)
==1797==    by 0x59DF007: vega::rknn::RknnMM::createVenc(unsigned long long, vega::MatrixType, vega::MatrixType, cv::Size_<int> const&, int, int, float, int, int, std::function<void (unsigned long long, std::shared_ptr<vega::Matrix>, DgError)>) (in /home/toybrick/Rockchip/zyh/t3r_pressure_test/T3RHeadDetectTest/release/aarch64-rk3399pro-linux/lib/libvega.so)
==1797==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==1797== 
==1797== Thread 5:
==1797== Mismatched free() / delete / delete []
==1797==    at 0x48494A0: operator delete(void*) (vg_replace_malloc.c:576)
==1797==    by 0x59F5AEB: std::_Sp_counted_ptr_inplace<vega::RpcData, std::allocator<vega::RpcData>, (__gnu_cxx::_Lock_policy)2>::_M_dispose() (in /home/toybrick/Rockchip/zyh/t3r_pressure_test/T3RHeadDetectTest/release/aarch64-rk3399pro-linux/lib/libvega.so)
==1797==    by 0x59F5C07: vega::StationInputPort::RpcNode::~RpcNode() (in /home/toybrick/Rockchip/zyh/t3r_pressure_test/T3RHeadDetectTest/release/aarch64-rk3399pro-linux/lib/libvega.so)
==1797==    by 0x59F839F: vega::DoableStation::work() (in /home/toybrick/Rockchip/zyh/t3r_pressure_test/T3RHeadDetectTest/release/aarch64-rk3399pro-linux/lib/libvega.so)
==1797==    by 0x7CE81F3: ??? (in /usr/lib/aarch64-linux-gnu/libstdc++.so.6.0.25)
==1797==    by 0x48A67E3: start_thread (pthread_create.c:486)
==1797==    by 0x7FA5ADB: thread_start (clone.S:78)
==1797==  Address 0x121c2b20 is 0 bytes inside a block of size 36,852 alloc'd
==1797==    at 0x484A6DC: memalign (vg_replace_malloc.c:899)
==1797==    by 0x58FAF27: vega::Matrix::createMemory(unsigned int, unsigned int) (in /home/toybrick/Rockchip/zyh/t3r_pressure_test/T3RHeadDetectTest/release/aarch64-rk3399pro-linux/lib/libvega.so)
==1797==    by 0x58F5227: vega::Matrix::create(vega::MatrixProperty const&, int) (in /home/toybrick/Rockchip/zyh/t3r_pressure_test/T3RHeadDetectTest/release/aarch64-rk3399pro-linux/lib/libvega.so)
==1797==    by 0x59E487F: vega::rknn::Venc::procPacketData(void*) (in /home/toybrick/Rockchip/zyh/t3r_pressure_test/T3RHeadDetectTest/release/aarch64-rk3399pro-linux/lib/libvega.so)
==1797==    by 0x59E59F3: vega::rknn::Venc::getVencData() (in /home/toybrick/Rockchip/zyh/t3r_pressure_test/T3RHeadDetectTest/release/aarch64-rk3399pro-linux/lib/libvega.so)
==1797==    by 0x59E5B5B: vega::rknn::Venc::getVencStreamThread(void*) (in /home/toybrick/Rockchip/zyh/t3r_pressure_test/T3RHeadDetectTest/release/aarch64-rk3399pro-linux/lib/libvega.so)
==1797==    by 0x48A67E3: start_thread (pthread_create.c:486)
==1797==    by 0x7FA5ADB: thread_start (clone.S:78)
==1797== 
==1797== 
==1797== HEAP SUMMARY:
==1797==     in use at exit: 26,728 bytes in 354 blocks
==1797==   total heap usage: 4,452 allocs, 4,098 frees, 23,635,141 bytes allocated
==1797== 
==1797== Thread 1:
==1797== 1,760 bytes in 5 blocks are possibly lost in loss record 180 of 182
==1797==    at 0x484A124: calloc (vg_replace_malloc.c:752)
==1797==    by 0x400FBD7: allocate_dtv (dl-tls.c:286)
==1797==    by 0x401047F: _dl_allocate_tls (dl-tls.c:532)
==1797==    by 0x48A7223: allocate_stack (allocatestack.c:621)
==1797==    by 0x48A7223: pthread_create@@GLIBC_2.17 (pthread_create.c:669)
==1797==    by 0x5CF4867: cv::WorkerThread::WorkerThread(cv::ThreadPool&, unsigned int) (in /home/toybrick/Rockchip/zyh/t3r_pressure_test/T3RHeadDetectTest/release/aarch64-rk3399pro-linux/lib/libvega.so)
==1797==    by 0x5CF5C53: cv::ThreadPool::reconfigure_(unsigned int) (in /home/toybrick/Rockchip/zyh/t3r_pressure_test/T3RHeadDetectTest/release/aarch64-rk3399pro-linux/lib/libvega.so)
==1797==    by 0x5CF64B3: cv::ThreadPool::run(cv::Range const&, cv::ParallelLoopBody const&, double) (in /home/toybrick/Rockchip/zyh/t3r_pressure_test/T3RHeadDetectTest/release/aarch64-rk3399pro-linux/lib/libvega.so)
==1797==    by 0x5CF32E3: cv::parallel_for_(cv::Range const&, cv::ParallelLoopBody const&, double) (in /home/toybrick/Rockchip/zyh/t3r_pressure_test/T3RHeadDetectTest/release/aarch64-rk3399pro-linux/lib/libvega.so)
==1797==    by 0x5ADBFEF: cv::hal::cpu_baseline::cvtBGRtoThreePlaneYUV(unsigned char const*, unsigned long, unsigned char*, unsigned long, int, int, int, bool, int) (in /home/toybrick/Rockchip/zyh/t3r_pressure_test/T3RHeadDetectTest/release/aarch64-rk3399pro-linux/lib/libvega.so)
==1797==    by 0x5ADD5DB: cv::cvtColorBGR2ThreePlaneYUV(cv::_InputArray const&, cv::_OutputArray const&, bool, int) (in /home/toybrick/Rockchip/zyh/t3r_pressure_test/T3RHeadDetectTest/release/aarch64-rk3399pro-linux/lib/libvega.so)
==1797==    by 0x5AA82B3: cv::cvtColor(cv::_InputArray const&, cv::_OutputArray const&, int, int) (in /home/toybrick/Rockchip/zyh/t3r_pressure_test/T3RHeadDetectTest/release/aarch64-rk3399pro-linux/lib/libvega.so)
==1797==    by 0x59E6C17: vega::rknn::Venc::videoEnc(std::shared_ptr<vega::Matrix>, float, bool) (in /home/toybrick/Rockchip/zyh/t3r_pressure_test/T3RHeadDetectTest/release/aarch64-rk3399pro-linux/lib/libvega.so)
==1797== 
==1797== 4,160 bytes in 1 blocks are definitely lost in loss record 182 of 182
==1797==    at 0x484A474: memalign (vg_replace_malloc.c:898)
==1797==    by 0x484A5AB: posix_memalign (vg_replace_malloc.c:1062)
==1797==    by 0x56132F3: os_malloc (os_mem.c:23)
==1797==    by 0x56127D3: mpp_osal_malloc (mpp_mem.cpp:646)
==1797==    by 0x561288F: mpp_osal_calloc (mpp_mem.cpp:666)
==1797==    by 0x55058DB: mpp_enc_cfg_init (mpp_enc_cfg.cpp:334)
==1797==    by 0x59E20BB: vega::rknn::Venc::creatVenc(int, int, int, int, int) (in /home/toybrick/Rockchip/zyh/t3r_pressure_test/T3RHeadDetectTest/release/aarch64-rk3399pro-linux/lib/libvega.so)
==1797==    by 0x59E2DDB: vega::rknn::Venc::creatVideoVenc(unsigned long long, int, int, int, int, float, int, int, std::function<void (unsigned long long, std::shared_ptr<vega::Matrix>, DgError)>) (in /home/toybrick/Rockchip/zyh/t3r_pressure_test/T3RHeadDetectTest/release/aarch64-rk3399pro-linux/lib/libvega.so)
==1797==    by 0x59DF007: vega::rknn::RknnMM::createVenc(unsigned long long, vega::MatrixType, vega::MatrixType, cv::Size_<int> const&, int, int, float, int, int, std::function<void (unsigned long long, std::shared_ptr<vega::Matrix>, DgError)>) (in /home/toybrick/Rockchip/zyh/t3r_pressure_test/T3RHeadDetectTest/release/aarch64-rk3399pro-linux/lib/libvega.so)
==1797==    by 0x5A66D0F: vega::rknn::VideoEncoder::procRpc(std::shared_ptr<vega::RpcContext>&) (in /home/toybrick/Rockchip/zyh/t3r_pressure_test/T3RHeadDetectTest/release/aarch64-rk3399pro-linux/lib/libvega.so)
==1797==    by 0x5A564DB: vega::RpcProcessor::processInternal(std::shared_ptr<vega::RpcData>) (in /home/toybrick/Rockchip/zyh/t3r_pressure_test/T3RHeadDetectTest/release/aarch64-rk3399pro-linux/lib/libvega.so)
==1797==    by 0x5A574F3: std::_Function_handler<void (), vega::RpcProcessor::process(std::shared_ptr<vega::RpcData>)::{lambda()#3}>::_M_invoke(std::_Any_data const&) (in /home/toybrick/Rockchip/zyh/t3r_pressure_test/T3RHeadDetectTest/release/aarch64-rk3399pro-linux/lib/libvega.so)
==1797== 
==1797== LEAK SUMMARY:
==1797==    definitely lost: 4,160 bytes in 1 blocks
==1797==    indirectly lost: 0 bytes in 0 blocks
==1797==      possibly lost: 1,760 bytes in 5 blocks
==1797==    still reachable: 20,808 bytes in 348 blocks
==1797==         suppressed: 0 bytes in 0 blocks
==1797== Reachable blocks (those to which a pointer was found) are not shown.
==1797== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==1797== 
==1797== For counts of detected and suppressed errors, rerun with: -v
==1797== ERROR SUMMARY: 5 errors from 5 contexts (suppressed: 0 from 0)

内存管理系统模块

  • 用户程序(Mutator)- 可以通过分配器创建对象或者更新对象持有的指针;

  • 内存分配器(Allocator)— 处理用户程序的的内存分配请求;

  • 垃圾收集器(Collector)- 标记内存中的对象并回收不需要的内存;

参考

内存管理设计精要

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

002237

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值