假设您有一个相当大(~2.2 MLOC)、相当老(10 多年前开始)C/C++ 的 Windows 桌面应用程序。大约 10% 的模块是外部的,没有源代码,只有调试符号。
您将如何将应用程序的内存占用减少一半?至少,你会怎么做才能找出内存消耗的地方?
假设您有一个相当大(~2.2 MLOC)、相当老(10 多年前开始)C/C++ 的 Windows 桌面应用程序。大约 10% 的模块是外部的,没有源代码,只有调试符号。
您将如何将应用程序的内存占用减少一半?至少,你会怎么做才能找出内存消耗的地方?
用包装器覆盖 malloc()/free() 和 new()/delete(),这些包装器跟踪分配的大小以及(通过记录调用堆栈并稍后根据符号表解析)它们的来源。在关机时,让你的包装器显示任何仍然分配的内存。
这应该使您能够确定最大的分配在哪里并捕获任何泄漏。
这是我用来将我们游戏的内存消耗减少 20% 的内存跟踪应用程序的描述/骨架。它帮助我跟踪外部模块完成的许多分配。
这不是一件容易的事。首先追查您能找到的任何内存泄漏(一个好的工具是Rational Purify)。浏览源代码并尝试优化数据结构和/或算法。
对不起,如果这听起来很悲观,但将内存使用量减少 50% 听起来并不现实。
There is a chance is you can find some significant inefficiencies very fast. First you should check what is the memory used for. A tool which I have found very handy for this is Memory Validator
Once you have this "memory usage map", you can check for Low Hanging Fruit. Are there any data structures consuming a lot of memory which could be represented in a more compact form? This is often possible, esp. when the data access is well encapsulated and when you have a spare CPU power you can dedicate to compressing / decompressing them on each access.
我不认为你的问题提出得很好。
源代码的大小与内存占用没有直接关系。当然,编译后的代码会占用一些内存,但应用程序可能会有自己的内存需求。静态(代码中声明的变量)和动态(应用程序创建的对象)。
我建议您分析程序执行并仔细研究代码。
对我来说,首先要开始的地方是:
应用程序是否做了很多预分配内存以供以后使用?这段记忆是否经常闲置而未使用,从未分发过?考虑根据需要切换到新/删除(或更好地使用 smart_ptr)。
代码是否使用静态数组,例如
Object arrayOfObjs[MAX_THAT_WILL_EVER_BE_USED];
并分发这个数组中的 objs?如果是这样,请考虑手动管理此内存。
内存使用分析工具之一是 LeakDiag,可从 Microsoft 免费下载。它显然允许将所有用户模式分配器挂接到 VirtualAlloc 并随时将进程分配快照转储到 XML。然后可以使用这些快照来确定哪些调用堆栈分配了大部分内存以及哪些调用堆栈正在泄漏。它缺少用于快照分析的漂亮前端(除非您可以通过 Microsoft Premier Support 获得 LDParser/LDGrapher),但所有数据都在那里。
还要注意的一件事是,由于缓存,您可能会从 BSTR 分配器中获得误报泄漏,请参阅“嘿,为什么我要泄漏所有 BSTR?”