【问题标题】:Profiling DLL/LIB Bloat分析 DLL/LIB 膨胀
【发布时间】:2010-12-08 14:16:33
【问题描述】:

我在 VS2005 中继承了一个相当大的 C++ 项目,它编译成大约 5MB 的 DLL。我想减小库的大小,以便为从慢速网络共享中使用它的客户更快地通过网络加载。

我知道如何通过分析代码、包含和项目设置来做到这一点,但我想知道是否有可用的工具可以更轻松地确定代码的哪些部分占用的空间最多。有没有办法生成 DLL 布局的“配置文件”?报告库图像中的哪些内容占用了空间以及占用了多少空间?

【问题讨论】:

  • 压缩后文件有多大?也许压缩/解压缩将是一种无需太多更改即可修复它的方法-因为您说您继承了它。不确定您是否会从中获得那么多,这取决于您的架构。
  • 对于后人,我发现这个问题密切相关:stackoverflow.com/questions/577330/…

标签: c++ visual-studio optimization dll profiling


【解决方案1】:

所有好的建议。我所做的是获取地图文件,然后只关注它。我过去发现的一种情况是,很大一部分空间被一个或多个类库占用,这是因为某处的某个变量被声明为具有听起来可以节省一些编码的类型努力,但实际上并不是必需的。

就像在 MFC 中一样(还记得吗?),它们有一个包装类来处理 Win32 提供的控件、字体等所有内容。这些会占用大量空间,而您并不总是需要它们。

另一个可能会占用大量空间的东西是你可以不用管理的集合类。另一个是你不使用的 cout I/O 例程。

【讨论】:

    【解决方案2】:

    鉴于所有 .obj 文件的大小大致相同,假设您使用的是预编译头文件,请尝试创建一个空的 obj 文件并查看它有多大。这将使您了解由于 PCH 编译而导致的每个 .obj 的比例。顺便说一句,链接器将能够删除那里的所有重复项。或者,您可以尝试禁用 PCH,以便 obj 文件可以更好地指示主要罪魁祸首在哪里。

    【讨论】:

      【解决方案3】:

      如果您的 DLL 之所以这么大,是因为它导出的 C++ 函数具有异常长的重整名称,另一种方法是使用 .DEF 文件按序数导出函数,不带名称(在 .DEF 文件中使用 NONAME) .有点脆弱,但它减少了 DLL 大小、EXE 大小和加载时间。

      参见例如http://home.hiwaay.net/~georgech/WhitePapers/Exporting/Exp.htm

      【讨论】:

        【解决方案4】:

        如果您的最终目标只是缩小 DLL 的大小,那么在调整编译器设置之后,您可能会通过通过UPX 运行 DLL 来获得最快的结果。 UPX 是一款出色的 DLL 和 EXE 压缩实用程序;它也是具有非病毒许可的开源软件,因此可以在商业/闭源产品中使用。

        我只让它在最高压缩设置(蛮力选项)上出现病毒警告,所以如果你使用比这更低的设置,你可能会没事。

        【讨论】:

          【解决方案5】:

          您也可以尝试静态链接而不是使用 dll。实际上,当库被静态链接时,链接器会从最终的 exe 中删除所有未使用的函数。有时最终的 exe 只是稍微大一点,而你没有更多的 dll。

          【讨论】:

            【解决方案6】:

            我会推荐以下之一:

            覆盖率 - 你可以运行一个覆盖率工具来检测一些死代码

            缓存 - 在初始激活时缓存客户端的dll

            拆分 - 将 dll 拆分为几个较小的 dll,使用 bootstrap dll 启动应用程序,并在应用程序启动后下载其他 dll

            编译和链接 - 使用较小的运行时库,使用大小优化等进行编译。请参阅此link 以获得更多建议。

            压缩 - 如果您的 dll 中有数据或大型资源,您可以在下载后或运行时对其进行压缩和解压缩。

            【讨论】:

            • “此链接”似乎丢失了。
            【解决方案7】:

            在构建 DLL 时,可以将 /MAP 传递给链接器,让它生成一个映射文件,其中包含生成的图像中所有符号的地址。您可能需要编写一些脚本来计算每个符号的大小。

            使用"strings" utility 扫描您的 DLL 可能会发现意外或未使用的可打印字符串(例如资源、RCS ID、__FILE__ 宏、调试消息、断言等)。

            此外,如果您尚未在启用 /Os 的情况下进行编译,那么值得一试。

            【讨论】:

            【解决方案8】:

            虽然我不知道任何二进制大小分析器,但您也可以查找最大的目标文件 (.obj) - 这至少可以让您了解问题点在哪里。
            当然,这需要一个充分模块化的项目。

            【讨论】:

            • 这是个好建议。问题是它们的大小都差不多。大约有 30 个模块,目标代码文件都在 800kb 左右。因此,似乎链接器正在智能地消除一些重叠,但我想深入了解剩余部分的组成。
            • 我可以想象这样的尺寸分析应该可以通过生成调试信息来实现 - 但遗憾的是我还没有听说过任何工具。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2011-09-23
            • 2016-09-29
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多