OpenCV中文网站

 找回密码
 立即注册
搜索
热搜: 安装 配置
查看: 10610|回复: 12

opencv 2.4.5 中的代码泄漏问题

[复制链接]
发表于 2013-8-31 14:49:28 | 显示全部楼层 |阅读模式
RT,在最近使用opencv开发的项目里,出现了系统泄漏,经过我一周的排查,定位到两个函数上,一个是cv::resize,一个是cvtColor。我使用的是微软的CRT库中的_CrtDumpMemoryLeaks()做的检测,很想知道是不是因为我的检测方法有问题。(真希望是我检测的问题)

具体来讲,对于前一个函数,我发现resize之后的大小比原图大时会发生内存泄漏。

而对于函数cvtColor,我还没有找到问题,现将检测代码附上,望好心人告知是不是我调用函数出的问题,或者是我内存泄漏的检测方法有问题。

#include "StdAfx1.h"
#include "Interface.h"
#include "ImageUtility.h"


#ifdef _DEBUG
#define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__)
#else
#define DEBUG_CLIENTBLOCK
#endif
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#ifdef _DEBUG
#define new DEBUG_CLIENTBLOCK
#endif

int _tmain(int argc, _TCHAR* argv[])
{
    //_CrtSetBreakAlloc(1057620);
    int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
    tmpFlag |= _CRTDBG_LEAK_CHECK_DF;
    _CrtSetDbgFlag( tmpFlag );
    Mat mat = imread("d:\\test.jpg");
    Mat img;
    _CrtMemState s1, s2, s3;
    _CrtMemCheckpoint( &s1 );
    //while (1)
    {
        cvtColor(mat,img,CV_BGR2YCrCb);
    }
    _CrtMemCheckpoint( &s2 );
    if (_CrtMemDifference(&s3,&s1,&s2))
    {
        _CrtMemDumpStatistics(&s3);
    }
    return 0;
}

望各位走过路过的高手不吝赐教,小弟感激不尽!!



回复

使用道具 举报

发表于 2013-8-31 14:54:53 | 显示全部楼层
不是代码泄漏,是内存泄漏吧。cv::resize  cvtColor这俩函数应该没有问题。

你的这两个checkpoint之间的cvtColor函数内为img新申请了内存,所以造成泄漏假象。
你退出函数时,mat和img的内存都将通过析构函数释放,
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2013-8-31 15:05:54 | 显示全部楼层
Shiqi Yu 发表于 2013-8-31 14:54
不是代码泄漏,是内存泄漏吧。cv::resize  cvtColor这俩函数应该没有问题。

你的这两个checkpoint之间的cv ...

多谢于大回复!

刚才激动了,是内存泄漏,我打错了。

您说的这个我发完帖子之后也注意到了,但是不使用CrtMemCheckpoint 设定检测区间,直接在运行完代码之后检测,也是会报内存泄漏。

我也觉得这两个函数不应该出问题,深刻怀疑是自己检测方法的问题。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-8-31 15:23:40 | 显示全部楼层
Shiqi Yu 发表于 2013-8-31 14:54
不是代码泄漏,是内存泄漏吧。cv::resize  cvtColor这俩函数应该没有问题。

你的这两个checkpoint之间的cv ...

比如main函数改成这样,我这里也返回内存泄漏

int _tmain(int argc, _TCHAR* argv[])
{
    //_CrtSetBreakAlloc(1057620);
    int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
    tmpFlag |= _CRTDBG_LEAK_CHECK_DF;
    _CrtSetDbgFlag( tmpFlag );
    Mat mat = imread("d:\\test.jpg");
    Mat img;
    cvtColor(mat,img,CV_BGR2YCrCb);
    return 0;
}
回复 支持 反对

使用道具 举报

发表于 2013-8-31 23:56:22 | 显示全部楼层
以后贴代码请用代码标签
  1. int _tmain(int argc, _TCHAR* argv[])
  2. {
  3.     //_CrtSetBreakAlloc(1057620);
  4.     int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
  5.     tmpFlag |= _CRTDBG_LEAK_CHECK_DF;
  6.     _CrtSetDbgFlag( tmpFlag );
  7.     Mat mat = imread("d:\\test.jpg");
  8.     Mat img;
  9.     cvtColor(mat,img,CV_BGR2YCrCb);
  10.     return 0;
  11. }
复制代码
我的问题是:
1,对于你上面的代码,你检测出何等错误信息?
2, 你的opencv库链接的是什么版本的msvcrt?你现在编译的程序是链接什么版本的msvcrt?据我所知,最好链接同一个版本的msvcrt,因为不同版本的msvcrt对于new的处理方式似乎都不一样,而且你自己的程序代码里面从定义了new,但是opencv库是你之前就编译好的,你重定义了么?(估计没有重定义),这就带来很多问题。。。
3,你试着去掉 cvtColor(mat,img,CV_BGR2YCrCb); 这条语句看看,是否还有同样的内存泄漏?
4,调试跟踪进入相关代码,实际上从你这里看,代码也不是很复杂,如果你有调试版本的opencv,跟踪一下也很容易。
5,我以前发现opencv有一些全局变量的初始化过程,里面也会有new一些东西,结果MFC程序如果使用OpenCV也会经常报内存泄漏的问题,当然你的是console程序,应该和这种情况无关。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-9-1 14:27:48 | 显示全部楼层
ollydbg23 发表于 2013-8-31 23:56
以后贴代码请用代码标签我的问题是:
1,对于你上面的代码,你检测出何等错误信息?
2, 你的opencv库链接 ...

多谢回复!
1,对于你上面的代码,你检测出何等错误信息?
直接在调试器中运行上述代码,结果如下:
  1. Detected memory leaks!
  2. Dumping objects ->
  3. {489} normal block at 0x0000000001F7BA80, 128 bytes long.
  4. Data: <p LY            > 70 05 4C 59 00 00 00 00 D0 B5 F7 01 00 00 00 00
  5. {488} normal block at 0x0000000001F7B9F0, 32 bytes long.
  6. Data: <@               > 40 B5 F7 01 00 00 00 00 CD CD CD CD CD CD CD CD
  7. {487} normal block at 0x0000000001F7B950, 56 bytes long.
  8. Data: <                > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  9. {486} normal block at 0x0000000001F7B790, 336 bytes long.
  10. Data: <h LY            > 68 01 4C 59 00 00 00 00 CD CD CD CD CD CD CD CD
  11. {485} normal block at 0x0000000001F7B6A0, 128 bytes long.
  12. Data: <p LY            > 70 05 4C 59 00 00 00 00 D0 B5 F7 01 00 00 00 00
  13. {484} normal block at 0x0000000001F7B5D0, 96 bytes long.
  14. Data: <  LY            > C8 04 4C 59 00 00 00 00 1B 00 00 00 CD CD CD CD
  15. {483} normal block at 0x0000000001F7B540, 32 bytes long.
  16. Data: <                > 00 00 00 00 00 00 00 00 CD CD CD CD CD CD CD CD
  17. {482} normal block at 0x0000000001F7B4A0, 56 bytes long.
  18. Data: <                > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  19. {481} normal block at 0x0000000002008DD0, 336 bytes long.
  20. Data: <h LY            > 68 01 4C 59 00 00 00 00 CD CD CD CD CD CD CD CD
  21. {479} normal block at 0x0000000001F7AF00, 512 bytes long.
  22. Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
  23. {478} normal block at 0x0000000002008B60, 512 bytes long.
  24. Data: <                > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  25. {477} normal block at 0x0000000002008A20, 208 bytes long.
  26. Data: <        ?       > 02 00 00 00 02 00 00 00 3F 00 00 00 CD CD CD CD
  27. {475} normal block at 0x00000000020085C0, 568 bytes long.
  28. Data: <                > 00 00 02 00 02 00 00 00 F8 00 00 00 00 00 00 00
  29. {474} normal block at 0x0000000001F740E0, 24 bytes long.
  30. Data: <                > 00 00 00 00 00 00 00 00 F4 00 00 00 00 00 00 00
  31. {473} normal block at 0x0000000002008510, 64 bytes long.
  32. Data: <                > 00 00 00 00 CD CD CD CD CD CD CD CD CD CD CD CD
  33. {472} normal block at 0x0000000002008470, 56 bytes long.
  34. Data: <                > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  35. {470} normal block at 0x0000000002007FE0, 240 bytes long.
  36. Data: <  KY            > B8 8B 4B 59 00 00 00 00 CD CD CD CD CD CD CD CD
  37. {469} normal block at 0x0000000001FFFF70, 32776 bytes long.
  38. Data: <                > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  39. {468} normal block at 0x00000000023BE9F0, 16 bytes long.
  40. Data: <        p       > 01 10 00 00 01 00 00 00 70 FF FF 01 00 00 00 00
  41. {467} normal block at 0x0000000001F7AC90, 512 bytes long.
  42. Data: <                > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  43. {466} normal block at 0x0000000001F7AB10, 272 bytes long.
  44. Data: <  LY            > 08 09 4C 59 00 00 00 00 01 00 00 00 CD CD CD CD
  45. {465} normal block at 0x0000000001F7A8A0, 512 bytes long.
  46. Data: <                > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  47. {464} normal block at 0x0000000001F7A720, 272 bytes long.
  48. Data: <  LY            > 08 09 4C 59 00 00 00 00 01 00 00 00 CD CD CD CD
  49. {463} normal block at 0x0000000001F7A4B0, 512 bytes long.
  50. Data: <                > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  51. {462} normal block at 0x0000000001F7A330, 272 bytes long.
  52. Data: <  LY            > 08 09 4C 59 00 00 00 00 00 00 00 00 CD CD CD CD
  53. {461} normal block at 0x0000000001FFFD00, 512 bytes long.
  54. Data: <                > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  55. {460} normal block at 0x0000000001FFFB80, 272 bytes long.
  56. Data: <  LY            > 08 09 4C 59 00 00 00 00 01 00 00 00 CD CD CD CD
  57. {459} normal block at 0x0000000001F792C0, 4096 bytes long.
  58. Data: <                > 00 FB FF 01 00 00 00 00 CD CD CD CD CD CD CD CD
  59. {458} normal block at 0x0000000001FFFB00, 24 bytes long.
  60. Data: <                > 90 F2 FF 01 00 00 00 00 00 00 00 00 00 00 00 00
  61. {457} normal block at 0x0000000001FFF290, 2048 bytes long.
  62. Data: <        0       > 80 FB FF 01 00 00 00 00 30 A3 F7 01 00 00 00 00
  63. {456} normal block at 0x0000000001FFF180, 160 bytes long.
  64. Data: <pA      P       > 70 41 F7 01 00 00 00 00 50 B3 FF 01 00 00 00 00
  65. {455} normal block at 0x0000000001F78250, 4096 bytes long.
  66. Data: <                > 00 F1 FF 01 00 00 00 00 CD CD CD CD CD CD CD CD
  67. {454} normal block at 0x0000000001FFF100, 24 bytes long.
  68. Data: <                > 90 E8 FF 01 00 00 00 00 00 00 00 00 00 00 00 00
  69. {453} normal block at 0x0000000001FFE890, 2048 bytes long.
  70. Data: <                > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  71. {452} normal block at 0x0000000001FFD820, 4096 bytes long.
  72. Data: <                > A0 D7 FF 01 00 00 00 00 CD CD CD CD CD CD CD CD
  73. {451} normal block at 0x0000000001FFD7A0, 24 bytes long.
  74. Data: <0               > 30 CF FF 01 00 00 00 00 00 00 00 00 00 00 00 00
  75. {450} normal block at 0x0000000001FFCF30, 2048 bytes long.
  76. Data: <                > 20 8A 00 02 00 00 00 00 00 00 00 00 00 00 00 00
  77. {449} normal block at 0x0000000001FFCD50, 368 bytes long.
  78. Data: <  KY            > 08 F1 4B 59 00 00 00 00 00 00 00 00 00 00 00 00
  79. {448} normal block at 0x0000000001FFBCE0, 4096 bytes long.
  80. Data: <p ;             > 70 EB 3B 02 00 00 00 00 CD CD CD CD CD CD CD CD
  81. {447} normal block at 0x00000000023BEB70, 24 bytes long.
  82. Data: <p               > 70 B4 FF 01 00 00 00 00 00 00 00 00 00 00 00 00
  83. {446} normal block at 0x0000000001FFB470, 2048 bytes long.
  84. Data: <P               > 50 CD FF 01 00 00 00 00 00 00 00 00 00 00 00 00
  85. {445} normal block at 0x0000000001FFB350, 176 bytes long.
  86. Data: <pA              > 70 41 F7 01 00 00 00 00 80 F1 FF 01 00 00 00 00
  87. {444} normal block at 0x0000000001FFB260, 128 bytes long.
  88. Data: <  KY      KY    > 08 8E 4B 59 00 00 00 00 F8 89 4B 59 00 00 00 00
  89. {443} normal block at 0x0000000001FFB170, 128 bytes long.
  90. Data: <  KY      KY    > 08 8E 4B 59 00 00 00 00 F8 89 4B 59 00 00 00 00
  91. {442} normal block at 0x0000000001FFB080, 128 bytes long.
  92. Data: <  KY      KY    > 08 8E 4B 59 00 00 00 00 F8 89 4B 59 00 00 00 00
  93. {441} normal block at 0x00000000023BEA80, 128 bytes long.
  94. Data: <  KY      KY    > 08 8E 4B 59 00 00 00 00 F8 89 4B 59 00 00 00 00
  95. {439} normal block at 0x00000000023BE7E0, 4 bytes long.
  96. Data: <    > 00 00 00 00
  97. {438} normal block at 0x0000000001F75660, 224 bytes long.
  98. Data: <                > 01 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
  99. {437} normal block at 0x0000000001F755C0, 56 bytes long.
  100. Data: <                > 0F 00 00 00 00 00 00 00 04 00 00 00 04 00 00 00
  101. {436} normal block at 0x0000000001F74D20, 2104 bytes long.
  102. Data: <                > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  103. {435} normal block at 0x00000000023BE870, 272 bytes long.
  104. Data: <X KY            > 58 E3 4B 59 00 00 00 00 D0 B5 F7 01 00 00 00 00
  105. {433} normal block at 0x00000000023BE770, 8 bytes long.
  106. Data: <        > 80 F1 FF 01 00 00 00 00
  107. {432} normal block at 0x00000000023BEF70, 8 bytes long.
  108. Data: <P       > 50 B3 FF 01 00 00 00 00
  109. {431} normal block at 0x00000000023BEE80, 128 bytes long.
  110. Data: <  ;             > E0 E8 3B 02 00 00 00 00 CD CD CD CD CD CD CD CD
  111. {430} normal block at 0x00000000023BEE00, 16 bytes long.
  112. Data: <                > 00 00 00 00 01 00 00 00 02 00 00 00 03 00 00 00
  113. {429} normal block at 0x00000000023BED30, 96 bytes long.
  114. Data: <                > 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
  115. {428} normal block at 0x00000000023BECC0, 4 bytes long.
  116. Data: <    > 00 00 00 00
  117. {427} normal block at 0x00000000023BEC20, 56 bytes long.
  118. Data: <                > 0F 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00
  119. {425} normal block at 0x00000000023BE610, 248 bytes long.
  120. Data: <  KY            > D0 A5 4B 59 00 00 00 00 02 00 00 00 01 00 00 00
  121. {424} normal block at 0x00000000023BE590, 16 bytes long.
  122. Data: <( KY    pA      > 28 ED 4B 59 00 00 00 00 70 41 F7 01 00 00 00 00
  123. {423} normal block at 0x00000000023BD520, 4096 bytes long.
  124. Data: <                > B0 80 F7 01 00 00 00 00 CD CD CD CD CD CD CD CD
  125. {422} normal block at 0x0000000001F780B0, 24 bytes long.
  126. Data: < D              > B0 44 F7 01 00 00 00 00 00 00 00 00 00 00 00 00
  127. {421} normal block at 0x0000000001F744B0, 2048 bytes long.
  128. Data: <                > 10 85 00 02 00 00 00 00 00 00 00 00 00 00 00 00
  129. {420} normal block at 0x0000000001F74420, 36 bytes long.
  130. Data: <                > 00 00 00 00 04 00 00 00 01 00 00 00 01 00 00 00
  131. {419} normal block at 0x0000000001F74170, 576 bytes long.
  132. Data: <  KY     D      > 98 FF 4B 59 00 00 00 00 20 44 F7 01 00 00 00 00
  133. Object dump complete.
复制代码
2, 你的opencv库链接的是什么版本的msvcrt?你现在编译的程序是链接什么版本的msvcrt?据我所知,最好链接同一个版本的msvcrt,因为不同版本的msvcrt对于new的处理方式似乎都不一样,而且你自己的程序代码里面从定义了new,但是opencv库是你之前就编译好的,你重定义了么?(估计没有重定义),这就带来很多问题。。。
这个问题我不太懂,回头找一些材料研究一下,多谢指导!

3,你试着去掉 cvtColor(mat,img,CV_BGR2YCrCb); 这条语句看看,是否还有同样的内存泄漏?
去掉的话,没有内存泄漏

4,调试跟踪进入相关代码,实际上从你这里看,代码也不是很复杂,如果你有调试版本的opencv,跟踪一下也很容易。
我跳进去过,进去cvColor里面,但是也没有发现开辟未释放的内存,所以比较奇怪
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-9-1 15:07:37 | 显示全部楼层
本帖最后由 小熊数星星 于 2013-9-1 15:09 编辑
ollydbg23 发表于 2013-8-31 23:56
以后贴代码请用代码标签我的问题是:
1,对于你上面的代码,你检测出何等错误信息?
2, 你的opencv库链接 ...

针对您说得第二点,想多请教几句:
1.如何查看opencv库链接的msvcrt的版本?
2.本机重新编译opencv的话,链接版本会不会一致?我试过官方自带的opencv库和自己本机编译的,报的泄漏一样。
3.去掉我程序中重定义的new,依然有同样的内存泄漏报告。
4.假如此问题真是不同版本的msvcrt造成的,那是造成的内存泄漏检测误报呢?还是确实造成了内存泄漏?
回复 支持 反对

使用道具 举报

发表于 2013-9-1 23:34:23 | 显示全部楼层
小熊数星星 发表于 2013-9-1 14:27
多谢回复!
1,对于你上面的代码,你检测出何等错误信息?
直接在调试器中运行上述代码,结果如下:2,  ...

看了你的错误,我感觉这些错误提示,是由OpenCV的某些静态/全局变量初始化导致的,纯粹调用一个cvtColor函数不可能带来这么多的内存泄漏。
1.如何查看opencv库链接的msvcrt的版本?
2.本机重新编译opencv的话,链接版本会不会一致?我试过官方自带的opencv库和自己本机编译的,报的泄漏一样。
3.去掉我程序中重定义的new,依然有同样的内存泄漏报告。
4.假如此问题真是不同版本的msvcrt造成的,那是造成的内存泄漏检测误报呢?还是确实造成了内存泄漏?

1,msvcrt的版本很多,根据VC的不同,有多种版本,比如VC6.0对应的是msvcrt.dll,到了VC2003或者VC2005,就对应msvcrt110.dll和msvcrt210.dll之类的名字了。另外,同一个版本的msvcrt,也分为:多线程和非多线程,调试版本和非调试版本的区别(对应于不同名字的lib库),至于如何查看具体的版本,一个是用dependencywalk工具,另外就是看你的编译链接选项了。
2,一般来说,不能混杂使用msvcrt的不同版本,否则就可能有内存泄漏。至于你说同一版本的msvcrt也是这样,那估计是别的原因导致的了。
3,还是我和之前怀疑的一样,问题估计出在全局变量初始化的地方。
4,我以前在mfc下使用opencv时,发现内存泄漏确实是存在的,不是误报。

回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-9-2 11:06:57 | 显示全部楼层
ollydbg23 发表于 2013-9-1 23:34
看了你的错误,我感觉这些错误提示,是由OpenCV的某些静态/全局变量初始化导致的,纯粹调用一个cvtColor ...

1.我用dependencywalk查看了一下,opencv的dll和我生成的程序链接的都是MSVCR100D.dll,应该不是这个问题吧?
2.如果问题出在全局变量初始化的地方,那我应该如何规避解决呢?
3.我跳到_CrtDumpMemoryLeaks检测出来的地方,发现是这些地方出的问题:Concurrency::CurrentScheduler::Get(),我不太懂这个,是不是线程的问题,有没有线程需要自己释放这一说呢?
回复 支持 反对

使用道具 举报

发表于 2013-9-2 11:14:49 | 显示全部楼层
1.我用dependencywalk查看了一下,opencv的dll和我生成的程序链接的都是MSVCR100D.dll,应该不是这个问题吧?

从这个说明,你的opencv库和你自己的app程序链接的是同一个msvcrt的dll。
2.如果问题出在全局变量初始化的地方,那我应该如何规避解决呢?
我印象中,你看看在OpenCV的库源代码里面,有没有DllMain这个函数,我以前发现这个函数被反复调用(针对不同的event),导致几个全局变量多次申请内存了。
3.我跳到_CrtDumpMemoryLeaks检测出来的地方,发现是这些地方出的问题:Concurrency::CurrentScheduler::Get(),我不太懂这个,是不是线程的问题,有没有线程需要自己释放这一说呢?
你看看有没有Concurrency的全局变量?或者CurrentScheduler的全局变量在OpenCV的源代码里面有定义的?
我手头没有visual c++。
我目前只有MinGW+GDB(而且我前些日子用MinGW编译的OpenCV是Release版本的,没法调试来复现你的问题)

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|OpenCV中文网站

GMT+8, 2024-6-12 12:38 , Processed in 0.010905 second(s), 16 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表