【问题标题】:Reducing memory footprint of large unfamiliar codebase减少大型不熟悉代码库的内存占用
【发布时间】:2010-09-12 11:27:00
【问题描述】:

假设您有一个相当大(~2.2 MLOC)、相当老(10 多年前开始)的 C/C++ Windows 桌面应用程序。大约 10% 的模块是外部的,没有源代码,只有调试符号。

您将如何将应用程序的内存占用减少一半?至少,你会怎么做才能找出内存消耗在哪里?

【问题讨论】:

    标签: c++ winapi optimization visual-c++ memory-management


    【解决方案1】:

    覆盖 malloc()/free() 和 new()/delete() 并使用包装器跟踪分配的大小以及(通过记录调用堆栈并稍后根据符号表解析)它们的来源.关闭时,让您的包装器显示任何仍分配的内存。

    这应该使您既可以确定最大分配的位置,又可以发现任何泄漏。

    【讨论】:

    • 您能否详细说明在应用程序范围内覆盖分配函数的最佳方法,最好是通过有限的源代码更改?此外,还有大量的 COM/BSTR 处理;我相信他们的分配器不能被排除在分析之外。
    【解决方案2】:

    this is description/skeleton 的内存跟踪应用程序我用来将我们游戏的内存消耗减少 20%。它帮助我跟踪外部模块完成的许多分配。

    【讨论】:

      【解决方案3】:

      这不是一件容易的事。首先追查你能找到的任何内存泄漏(一个好的工具是Rational Purify)。浏览源代码并尝试优化数据结构和/或算法。
      抱歉,这可能听起来很悲观,但将内存使用量减少 50% 听起来并不现实。

      【讨论】:

        【解决方案4】:

        您有可能很快就会发现一些明显的低效率问题。首先,您应该检查内存的用途。我发现一个非常方便的工具是Memory Validator

        一旦你有了这个“内存使用图”,你就可以检查低挂果。是否有任何消耗大量内存的数据结构可以以更紧凑的形式表示?这通常是可能的,尤其是。当数据访问被很好地封装并且当你有空闲的 CPU 能力时,你可以专注于在每次访问时压缩/解压缩它们。

        【讨论】:

        • 这取决于他的意思是“10 年前创建,之后没有变化”,还是“过去 10 年一直在有机地成长和积累垃圾”。第二类应用绝对是内存大户。
        • 它一直在增长。并积累。像往常一样,减少资源消耗的要求是从上面传递下来的。
        【解决方案5】:

        我不认为你的问题提出得很好。

        源代码的大小与内存占用没有直接关系。当然,编译后的代码会占用一些内存,但应用程序可能会有自己的内存需求。静态(代码中声明的变量)和动态(应用程序创建的对象)。

        我建议您分析程序执行并仔细研究代码。

        【讨论】:

        • 源代码的大小暗示了项目的整体复杂性。你认为“仔细研究”400 KLOC需要多少时间? :)
        • 应该很容易。 400k 不是我所说的大 :) 因为您只需要检查堆分配,找到所有 malloc 和 new 调用就可以了。
        • gbjbaanb,我希望我可以向您展示 just 模块依赖关系图 :) 并且关于“查找所有 malloc 和新的”,至少还有 SysAllocString(通常隐藏在 CComBSTRs 中)
        【解决方案6】:

        对我来说,首先要开始的地方是:

        应用程序是否会进行大量预分配内存以供以后使用?这段记忆是否经常闲置而未使用,从未分发过?考虑根据需要切换到新/删除(或更好地使用 smart_ptr)。

        代码是否使用静态数组如

        Object arrayOfObjs[MAX_THAT_WILL_EVER_BE_USED];
        

        然后分发这个数组中的对象?如果是这样,请考虑手动管理此内存。

        【讨论】:

          【解决方案7】:

          用于内存使用分析的工具之一是 LeakDiag,可用于free download from Microsoft。它显然允许将所有用户模式分配器挂接到 VirtualAlloc 并随时将进程分配快照转储到 XML。然后可以使用这些快照来确定哪些调用堆栈分配了大部分内存以及哪些调用堆栈正在泄漏。它缺少用于快照分析的漂亮前端(除非您可以通过 Microsoft Premier Support 获得 LDParser/LDGrapher),但所有数据都在那里。

          还有一点需要注意的是,由于缓存,您可能会从 BSTR 分配器中获得误报泄漏,请参阅 "Hey, why am I leaking all my BSTR's?"

          【讨论】:

            猜你喜欢
            • 2010-09-17
            • 1970-01-01
            • 2011-05-19
            • 2016-09-22
            • 1970-01-01
            • 1970-01-01
            • 2011-05-11
            • 1970-01-01
            相关资源
            最近更新 更多