【问题标题】:What Can I Do To Reduce My Executable's Size (Delphi)?我可以做些什么来减少我的可执行文件的大小(Delphi)?
【发布时间】:2011-03-13 02:02:15
【问题描述】:

我为使用 Delphi 2009 的桌面程序发布了一个可执行文件 (.EXE)。我没有运行该程序所需的外部 DLL 或资源。

我使用两个组件:LMD Innovative's ELPackSergey Tkachenko's TRichView,它们被编译到我的可执行文件中。

当我使用“发布”构建配置构建生产版本时,生成的可执行文件为 13,533 KB。

在使用 Delphi 2009 之前,我使用的是 Delphi 4。它生成的可执行文件只有 2,671 KB,同时包含相同的两个组件,并且与我当前版本的代码基本相同。

我知道 Delphi 2009 完全是 Unicode(这是我升级的主要原因),并且是 Unicode 可能会导致大小翻倍。但这大约是 5 倍。

我的可执行文件必须保持 5 倍大吗?还是有一些简单的方法可以减少大量可执行文件的大小?


请注意。有些人正在回答压缩 Delphi EXE 的方法。那不是我想要做的。我试图简单地了解为什么要使用如此多的空间来删除​​可能不需要的东西。如果这样做了,如果需要,之后仍然可以进行压缩。

安装后可执行文件的大小实际上并不重要。它用于下载目的,并最大限度地减少您要压缩它的服务器负载和下载时间。我更喜欢使用Inno Setup 并在安装例程本身中压缩程序。然后在安装时将其扩展为全尺寸。这既可以防止可能被检测为病毒,又可以消除在内存中解压缩程序所需的额外启动时间。此外,我对我的可执行文件和我的安装例程都进行了代码签名,并且一些压缩技术与之不兼容。

有关压缩的更多信息,请参阅 StackOverflow 问题:Delphi EXE compressor?


ldsandon 要求我准确提供我正在使用的选项,所以他们在这里:


(来源:beholdgenealogy.com


(来源:beholdgenealogy.com

【问题讨论】:

  • 您当前使用的是哪个编译器开关?对代码大小影响最大的是向项目添加调试信息或控制代码的那些。
  • @splash:我有大约 400 KB 的自己的代码,大约 20 个单元。它们包括 14 个表格,使用 500 KB 的 dfm 文件。这不包括我使用的两个组件中的代码。
  • @ldsandon:我想我正在使用“发布”构建配置的所有默认值。
  • 我不再知道默认设置是什么,因为开箱即用的设置并不“正确”,我更改了它们并设置了另一个默认设置。 IIRC 他们启用了优化,但无论如何添加一些调试信息,检查字符串格式等等。了解您实际使用的选项会很有用。
  • 尝试 DebugDCUs = OFF,Map File = OFF

标签: delphi build-process executable


【解决方案1】:

当从 Delphi 7 迁移到 Delphi 2010 时,我们的 .exe 文件从 16 兆增加到 35 兆。

几周前,我在 Embarcadero 论坛上问了一个与您类似的问题。 (link) 在我的 OP 中,我列出了一系列关于此主题的链接,您可能会觉得有帮助。

我们尝试使用 UPX 压缩我们的 .exe。让它工作几个小时显着减少了我们的 .exe,但我们可能不会在生产中使用它,原因如下:

  1. 我们有很多 .exe 文件,不想在每个版本上等待 1/2 天。 (我们有可能找到 UPX 的非暴力参数集来减少这种情况......)

  2. 虽然 .exe 的大小减小了,但我们的 可交付 没有,因为我们的安装程序(不足为奇)无法从已经压缩的文件中压缩更多的压缩...而它能够将原来的 16 兆 .exe 减少到 8 兆。

  3. 我读过一些报告,有时(很少,但并非从来没有),UPX exe 触发了各种防病毒程序来报告应用程序包含病毒。 (我不记得我看到这个的日期、地点或细节,所以我在这里报告它有点不公平。)但是,我们非常不愿意冒这种甚至可能发生的风险,UPX不在桌子上......

Embarcadero 论坛上的链接还包括一个 link 指向关于此主题的另一个 SO 线程。

在迁移到 Delphi 2010 时,我仍然对我们发现的代码膨胀感到惊讶和失望。正如 Nick 指出的那样,Unicode 的 2X 是相当多的。

但是,在迁移到 D2010 时,膨胀是一个相对较小的权衡,因为在 IMO 中,D2010 在许多其他方面都是如此了不起的升级。但是,它确实意味着我们可能不得不转向运送 2 张 CD 而不是一张。我不期待看到我们组织对此的反应......

【讨论】:

  • @Tom1952:你不能压缩两次。因此最好使用安装程序进行压缩以减少下载大小。我使用 InnoSetup,它将我的 13.5 MB 程序包含在一个只有 4.5 MB 的安装程序包中。运行安装程序时,它会将程序解压缩到完整大小,因此不会有任何可能的病毒检测问题。
  • @Tom1952:感谢您在 Embarcadero 论坛上提供指向您类似问题的链接。这是一个非常有趣的讨论(包括 Peter 下面的一些 cmets)。你提到的一点是关于大图标的。好吧,我确实在我的程序中添加了一些大的 Vista 图标,这些图标本来可以增加一个 MB 的大小。也许你写的程序可能对我有帮助。
  • @Tom1952:我还没有看到其他 SO 问题。这是一个很好的想法和一些有用的实用程序的链接。
  • D2010 是另一回事,因为它扩展了 RTTI 可能性,我可以想象错误的管理(在任何地方打开它)可能会使 exe 膨胀。 OP 说的是 D2009。
  • UPX 触发误报当然是一种风险。但是您也可以通过您的设置、任何库或使用任何特定的开发环境(Delphi、VS 等)来获得相同的结果。因此,虽然您无法消除风险,但通过跳过 UPX 来减少风险因素的数量是合理的。
【解决方案2】:

没有看到您的“发布”构建配置使用的实际设置来解释这种大小增加需要大量推测。

除了一些可能不太可能导致“拖入”的代码量(即使没有使用)大量增加之外,这种增加的幅度很容易通过包含调试信息来解释。

我会检查您的编译器和链接器设置:

  • 调试信息(编译器设置)
  • TD32 信息(链接器)
  • 远程调试信息(链接器)

将您的 Delphi 2009 项目中的这些设置与 Delphi 4 中的等效设置进行比较。

【讨论】:

  • 谢谢@Deltics:我相信我正在使用所有默认的 Delphi 2009“发布”设置。在 Delphi 2009 中,TD32 设置已替换为链接调试信息(请参阅:blogs.embarcadero.com/chrishesik/2009/09/15/34920),我将其设置为“False”。链接器中的远程调试符号为 False。但是我确实将调试信息编译为 True,将符号调试为 True 和本地符号奇怪地与它们相反为 False。然后链接器输出为 Generate DCUs,Map File 为Detailed。我可以和他们一起玩,但如果他们能救我很多,我会感到惊讶。
  • 您可能会惊讶于调试信息能带来多大的不同。至少值得将其关闭并找出答案。另外,您是否使用了 MadExcept 或任何类似的实用程序,它们可能会在构建后步骤中将 MAP 文件嵌入到您的可执行文件中?
  • @Deltics:我确实使用 EurekaLog 来跟踪错误,但我关闭了它的大部分选项(包括内存泄漏)。完全关闭 EurekaLog 只会将可执行文件减少 90 KB。
  • @lkssler,EurekaLog 有一个奇怪的习惯,即在启用时为您的 exe 打开调试信息。您是否尝试禁用 EurekaLog,然后关闭构建配置中的所有“调试”选项,然后再次构建? 90Kb 的大小不足以删除调试信息。我放弃了 EurekaLog,因为它弄乱了我的构建配置,再也没有回头。
  • 查看您的编译器选项,您为什么要链接调试 dcus?这些更大,可能会阻止链接器删除未使用的代码,可能会更慢。
【解决方案3】:

从 Unicode 中扣除预期的 2 倍增长,您最终会得到 2.5 倍的增长。考虑到您跳过了多少个版本,这是有道理的。自 Delphi 4 以来,VCL 和 RTL 中添加了很多内容,即使您从未使用过,也并非所有内容都可以轻松智能链接。根据您使用的单位数量,您可能会拖运相当多的额外行李。

Allen Bauer 和编译器团队添加了 a new feature into D2010 to help reduce this,但显然他们在谨慎行事,并没有在尽可能多的地方使用它。希望我们会在 2011 年和后续版本中看到更多的减少。

【讨论】:

  • 我知道。它比这要少一些,因为并非应用程序中的所有内容都是字符串。但我的主要观点是,其中很多来自标准库变得越来越大。
  • 我的下一个主要升级将是 64 位或跨平台编译,以先到者为准。我希望我的可执行文件不会增长到 30 MB。
  • 64 位确实比相同的 x86 更庞大。但仅适用于代码,问题是这是否都是代码。正如梅森所说,要回答这个问题,我们必须找出导致(至少)2.5X 因素未得到解释的原因
  • 那些年看了很多电视却变笨的“智能链接器”怎么样? ;) ...智能链接器不会丢掉很多不需要的东西,尽管它在生成的二进制文件中毫无用处,因此它并不像它的创建者想象的那么聪明。
【解决方案4】:

我将添加我的几句话。 只有遵循代码层次结构,链接器才能删除未使用的过程和函数。下面列出的链接器的噩梦列表:

  • 消息驱动的代码,不幸的是,这个代码无论如何都不能被删除,这就是为什么 Delphi 空白项目的大小不断地从一个版本到另一个版本增长。每条新的 Windows 消息(例如 WM_TOUCH,只要我知道最近介绍)都会创建无法删除的过程调用层次结构(即使您根本没有计划使用 Touch API)。这是因为每个 case WM_: 片段都是链接器无法决定是否使用它的东西。

  • 从单元的开始、初始化、结束部分访问的代码和数据结构。在这里您可以进行一些控制,删除不必要的调用或对象创建。即使您按需创建对象并仅在完成部分释放它们,也要小心制作

【讨论】:

    【解决方案5】:

    使用“upx - 压缩或展开可执行文件”@http://upx.sourceforge.net


    如果您转到工具/配置工具,并像这样进行设置,您可以通过 IDE 中的菜单项轻松压缩您正在处理的可执行文件。

    【讨论】:

    • IMO,您最好将 UPX 留到部署过程的后期。即不要在IDE中打扰它,它只会减慢你的速度。等到您准备好进行部署,然后在您共同设计、本地化、构建设置等的同一个工作(.bat 文件、Visual Build Pro 等)中进行。
    • 我问的问题不是简单地减小可执行文件的大小,而是找出任何无用的多余大小并找出为什么它在 Delphi 版本之间增长如此之快。为了减少下载时间,我使用 InnoSetup 创建一个压缩的安装文件。请参阅我对 Tom1952 的回答的评论。
    【解决方案6】:

    另一种方法是查看“什么单位增加了大小?”。

    为此,我使用了 JCL“项目分析器 IDE”,它与 JCL/JVCL 安装集成在 IDE 中,它会向您显示所有单元及其各自的大小。您可以将其导出为文本文件。 如果您使用 2 个环境(D4 和 D2009)进行操作,您将获得很多相关信息。

    【讨论】:

    • 比@philnext。不幸的是,我去新机器时没有重新安装Delphi 4。我需要旧版本的 ElPack 和 TRichView 才能使用它,我记得当时安装它们是个麻烦事,所以这不值得费心,特别是因为我的新代码是 Unicode 并且现在与 Delphi 4 完全不兼容。
    • 这实际上是一个很好的方法来寻找那些作为 3MB 位图潜入表单的讨厌的 16k PNG 图像。
    【解决方案7】:

    我做了一些测试来看看 D2007 和 D2010 之间的区别,因为我们正在升级到 D2010。我测试了一个中型管理 GUI 应用程序,大约有 60 个表单(带有详细表单、框架等的网格)。我们正在使用 TMS 组件 + Remobjects。

    D2007:
    “正常”编译:18.8mb
    带调试 dcu:18.8mb(相同大小!)

    D2010
    正常:23.9
    调试 dcu:48.8mb (!)

    所以使用 debug dcu 会使我们的 exe 大小翻倍...

    使用我们的业务服务进行测试(没有大的 dfm):
    D2007:12.3mb
    D2010:17.1mb

    所以是的,D2010 增加了 exe(一点点),但这对我的客户来说不是问题。

    编辑:有关编译大小的一些信息:
    D2007:

    D2010:

    因此增加了代码大小,但数据增加了一倍多!

    【讨论】:

      【解决方案8】:

      检查 dfm-s 的格式。如果你想让你的 exe 更小,它们必须是二进制格式。

      【讨论】:

        【解决方案9】:

        如果你不想使用 exe 压缩器,那么你应该试试StripReloc

        【讨论】:

        • 但是你可以使用 StripReloc 和压缩器。
        • 查看我对亚当回答的评论。
        • stripreloc 很好(因为它不是压缩器)但它不能减小大小
        • StripReloc 确实减少了 exe 的大小,但您可以使用 {$SetPEFlags IMAGE_FILE_RELOCS_STRIPPED}
        【解决方案10】:

        1) 您正在生成一个详细的映射文件,并且因为您设置了“使用调试 dcus”,它还将包含 RTL/VCL 单元的符号。如果异常处理系统使用它来生成调用堆栈等,则可以将其添加到可执行文件中。如果不以某种方式压缩,它可能会使您的 .exe 大小变得非常大。

        2) 使用 debug dcus 也会使你的 .exe 文件更大一些,因为它们通常是在没有优化和调试选项设置的情况下编译的,它们也会使你的代码变慢。它们不应在发布版本中使用。

        3) 调试信息应该只将 debig 信息添加到单元而不是可执行文件,尽管它需要 IIRC 来生成映射文件。

        【讨论】:

          【解决方案11】:

          由于 D2010 添加了扩展 RTTI,而 RTTI 是增加 exe 大小的一个臭名昭著的因素,因此看看 D2009 二进制文件对于该应用程序有多大会很有趣。

          如果 D2009 二进制文件明显更小,则不是 Unicode 等。对于我自己的二进制文件,从 D7 到 D2009 仅增加了 30% 左右。

          【讨论】:

            【解决方案12】:

            前面已经说过,使用可执行压缩器会减小 exe 的大小,但不会减小安装包的大小。但是,如果您想要一个好的压缩器,请尝试ASPack

            @Tom1952:ASPack 相当快,压缩一个文件只需几秒钟

            【讨论】:

            • 是的,大家都知道exe压缩器可以压缩exe,ASpacks是一个很好的压缩器,但这不是讨论哪个压缩器最好的问题
            【解决方案13】:

            您也可以更改图标。最新的delphi IDE(即XE3)中的图标与Vista/7 兼容并且包含所有尺寸(据我所知最大为256x256)。因此,您可以通过更改图标来减小 exe 文件的大小。

            【讨论】:

              【解决方案14】:

              较新的 delphi 中的标准单元可能包含更多的字符串和常量,例如错误字符串,即使您禁用调试信息也会包括在内。检查您的用途。

              除了不使用特定单位或从中删除不需要的数据之外,别无他求。

              (我的经验是使用 Delphi 5)

              【讨论】:

                【解决方案15】:

                对于带有默认设置的 Delphi 10.3 Rio:

                第 1 步:在“项目”窗口中从 Debug 切换到 Release。这将我的 exe 文件从 22 MB 减少到 5 MB!

                第 2 步:使用 exe 压缩器,如 ASPack。它进一步将我的 exe 文件减少到 1.3 MB。难以置信,不是吗? :)

                【讨论】:

                  【解决方案16】:

                  取消选中项目选项中的调试信息。 如果 embarcadero 无法提供任何解决方案或解释!!!我认为解决办法很简单:不要只停留在Delphi,有很多编程语言,每一种都只受程序员想象力的限制。

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2012-10-11
                    • 1970-01-01
                    • 1970-01-01
                    • 2012-09-02
                    相关资源
                    最近更新 更多