【发布时间】:2010-09-12 11:27:00
【问题描述】:
假设您有一个相当大(~2.2 MLOC)、相当老(10 多年前开始)的 C/C++ Windows 桌面应用程序。大约 10% 的模块是外部的,没有源代码,只有调试符号。
您将如何将应用程序的内存占用减少一半?至少,你会怎么做才能找出内存消耗在哪里?
【问题讨论】:
标签: c++ winapi optimization visual-c++ memory-management
假设您有一个相当大(~2.2 MLOC)、相当老(10 多年前开始)的 C/C++ Windows 桌面应用程序。大约 10% 的模块是外部的,没有源代码,只有调试符号。
您将如何将应用程序的内存占用减少一半?至少,你会怎么做才能找出内存消耗在哪里?
【问题讨论】:
标签: c++ winapi optimization visual-c++ memory-management
覆盖 malloc()/free() 和 new()/delete() 并使用包装器跟踪分配的大小以及(通过记录调用堆栈并稍后根据符号表解析)它们的来源.关闭时,让您的包装器显示任何仍分配的内存。
这应该使您既可以确定最大分配的位置,又可以发现任何泄漏。
【讨论】:
this is description/skeleton 的内存跟踪应用程序我用来将我们游戏的内存消耗减少 20%。它帮助我跟踪外部模块完成的许多分配。
【讨论】:
这不是一件容易的事。首先追查你能找到的任何内存泄漏(一个好的工具是Rational Purify)。浏览源代码并尝试优化数据结构和/或算法。
抱歉,这可能听起来很悲观,但将内存使用量减少 50% 听起来并不现实。
【讨论】:
您有可能很快就会发现一些明显的低效率问题。首先,您应该检查内存的用途。我发现一个非常方便的工具是Memory Validator
一旦你有了这个“内存使用图”,你就可以检查低挂果。是否有任何消耗大量内存的数据结构可以以更紧凑的形式表示?这通常是可能的,尤其是。当数据访问被很好地封装并且当你有空闲的 CPU 能力时,你可以专注于在每次访问时压缩/解压缩它们。
【讨论】:
我不认为你的问题提出得很好。
源代码的大小与内存占用没有直接关系。当然,编译后的代码会占用一些内存,但应用程序可能会有自己的内存需求。静态(代码中声明的变量)和动态(应用程序创建的对象)。
我建议您分析程序执行并仔细研究代码。
【讨论】:
对我来说,首先要开始的地方是:
应用程序是否会进行大量预分配内存以供以后使用?这段记忆是否经常闲置而未使用,从未分发过?考虑根据需要切换到新/删除(或更好地使用 smart_ptr)。
代码是否使用静态数组如
Object arrayOfObjs[MAX_THAT_WILL_EVER_BE_USED];
然后分发这个数组中的对象?如果是这样,请考虑手动管理此内存。
【讨论】:
用于内存使用分析的工具之一是 LeakDiag,可用于free download from Microsoft。它显然允许将所有用户模式分配器挂接到 VirtualAlloc 并随时将进程分配快照转储到 XML。然后可以使用这些快照来确定哪些调用堆栈分配了大部分内存以及哪些调用堆栈正在泄漏。它缺少用于快照分析的漂亮前端(除非您可以通过 Microsoft Premier Support 获得 LDParser/LDGrapher),但所有数据都在那里。
还有一点需要注意的是,由于缓存,您可能会从 BSTR 分配器中获得误报泄漏,请参阅 "Hey, why am I leaking all my BSTR's?"
【讨论】: