解释 DrMemory 日志,内存泄漏 [关闭]

Posted

技术标签:

【中文标题】解释 DrMemory 日志,内存泄漏 [关闭]【英文标题】:Interpreting DrMemory log, memory leak [closed] 【发布时间】:2013-03-12 17:55:21 【问题描述】:

我使用 SDL api 编写了一个简单的贪吃蛇游戏,但游戏中的某个地方存在内存泄漏,因为在运行游戏大约 10 分钟后,它占用了超过 50mb 的内存并且它仍在扩展。我尽我所能找到泄漏,但我找不到它。我尝试使用 Dr Memory,但我无法完全理解它产生的日志。

这是有问题的日志: https://docs.google.com/file/d/0BwXrdShTcyjENmgyR2lrbTJ1aGc/edit?usp=sharing

【问题讨论】:

也许你可以切换到 Linux 并使用valgrind ? 可能是一些代码.. 听起来像是循环问题 根据日志,您有很多内存泄漏。例如,看看这里有什么:# 5 load_image() [L:/git/snake/src/main.cpp:144] # 6 load_files() [L:/git/snake/src/main.cpp:192] 我希望我能帮忙,但太阳耀斑正在干扰我的水晶球。要是有一些非通灵的方式来查看有问题的代码就好了…… 调用TTF_RenderText_Solid()后,需要调用SDL_FreeSurface() 【参考方案1】:

在您的 Dr. Memory 日志中,您可以看到有 3 个错误,计数约为 2899 次。 错误是:

Error # 154:   2899
Error # 155:   2899
Error # 369:   2898

所以,如果您查看错误:

Error #154: GDI USAGE ERROR: same bitmap 0x46052c24 selected into two different DC's 0x08012c43 and 0xbe012c3e
# 0 SDL.dll!SDL_UnregisterApp      +0x3063   (0x681304c3 <SDL.dll+0x304c3>)
# 1 SDL.dll!SDL_UpdateRect         +0x69     (0x68125d7a <SDL.dll+0x25d7a>)
# 2 SDL.dll!SDL_Flip               +0x52     (0x68125ff3 <SDL.dll+0x25ff3>)
# 3 draw()                          [L:/git/snake/src/main.cpp:133]
# 4 SDL_main                        [L:/git/snake/src/main.cpp:92]
# 5 console_main                    [./src/main/win32/SDL_win32_main.c:315]
# 6 WinMain@16                      [./src/main/win32/SDL_win32_main.c:398]
# 7 main                            [L:/git/snake/src/main.cpp:211]
Note: @0:00:04.148 in thread 3940

Error #155: GDI USAGE ERROR: DC 0x08012c43 that contains selected object being deleted
# 0 system call NtGdiDeleteObjectApp
# 1 GDI32.dll!DeleteDC                            +0xb6     (0x75b1596a <GDI32.dll+0x1596a>)
# 2 GDI32.dll!DeleteDC                            +0x11     (0x75b158c5 <GDI32.dll+0x158c5>)
# 3 SDL.dll!SDL_UnregisterApp                     +0x30c9   (0x6813052a <SDL.dll+0x3052a>)
# 4 SDL.dll!SDL_UpdateRect                        +0x69     (0x68125d7a <SDL.dll+0x25d7a>)
# 5 SDL.dll!SDL_Flip                              +0x52     (0x68125ff3 <SDL.dll+0x25ff3>)
# 6 draw()                                         [L:/git/snake/src/main.cpp:133]
# 7 SDL_main                                       [L:/git/snake/src/main.cpp:92]
# 8 console_main                                   [./src/main/win32/SDL_win32_main.c:315]
# 9 WinMain@16                                     [./src/main/win32/SDL_win32_main.c:398]
#10 main                                           [L:/git/snake/src/main.cpp:211]
Note: @0:00:04.149 in thread 3940

Error #369: LEAK 60 direct bytes 0x04c09070-0x04c090ac + 0 indirect bytes
# 0 SDL.dll!SDL_CreateRGBSurface         +0x8a     (0x681250cb <SDL.dll+0x250cb>)
# 1 SDL_ttf.dll!TTF_RenderUNICODE_Solid  +0xa6     (0x6f4c2e87 <SDL_ttf.dll+0x2e87>)
# 2 SDL_ttf.dll!TTF_RenderText_Solid     +0x62     (0x6f4c3253 <SDL_ttf.dll+0x3253>)
# 3 draw()                                [L:/git/snake/src/main.cpp:130]
# 4 SDL_main                              [L:/git/snake/src/main.cpp:92]
# 5 console_main                          [./src/main/win32/SDL_win32_main.c:315]
# 6 WinMain@16                            [./src/main/win32/SDL_win32_main.c:398]
# 7 main                                  [L:/git/snake/src/main.cpp:211]

您似乎在某个循环中分配了新内存,但忘记了释放。

对于标记为 LEAK 的错误 #369:调用TTF_RenderText_Solid() 后,您需要调用SDL_FreeSurface()

【讨论】:

【参考方案2】:

内存泄漏是由错误的动态分配使用(或弄乱指针)引起的。我猜你没有为小蛇游戏使用任何自定义动态分配,所以我猜你把SDL_Surface *弄乱了。

检查您使用SDL_Surface * 的每个地方。是否使用任何涉及在主游戏循环中创建(分配)新表面的代码?

创建(分配)新表面的SDL函数通常是SDL_LoadBMP()SDL_GetRGBSurface()SDL_SetVideoMode()。你在主游戏循环中使用它们中的任何一个吗?他们通常不应该在那里

或者也许您使用了任何动态分配?检查您的所有指针

【讨论】:

我消除了所有不需要的指针。剩下的唯一指针是我的蛇类指针和一些来自 sdl 的指针。我的 SDL 函数基于 Lazy Foo 的 SDL 教程。 然后正如我所说,检查你的 SDL 指针,它们不应该受到主循环内的 SDL_GetRGBSurfaceSDL_LoadBMP 的影响。如果不是,那么蛇类指针就是原因。你在主循环中使用new 作为你的蛇class 吗?如果是,那肯定是这个原因。 new 运算符是动态分配 new 在主循环的任何地方都没有使用。 没有new?你使用malloc() 还是 wut?还有,我忘了说! SDL_SetVideoMode() 也是动态分配,所以也不应该在主循环中! 循环中没有new,我只在main开头使用new来创建我的蛇类。嗯,SDL_SetVideoMode()init 函数中,是从main 函数调用的

以上是关于解释 DrMemory 日志,内存泄漏 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

Android内存泄漏的预防

log4j2线程的Tomcat内存泄漏问题

Java 内存不足。这不是内存泄漏吗?

expressjs文件下载内存泄漏

请解释一下“内存泄漏”,这个问题会有啥影响

Windows 7 清理 C++ 内存泄漏?