【问题标题】:Ways to make your program use less memory让你的程序使用更少内存的方法
【发布时间】:2009-03-01 02:33:51
【问题描述】:

软件会使用内存,这没什么大不了的,但是与您的程序有多大相比,您如何将这种使用量保持在最低限度。

我认为最好的例子是 Firefox。有些用户体验过,有些用户没有体验过,但可以肯定地说,所有以前版本的 Firefox 使用的内存都比当前版本多得多。然而,功能扩展并添加了选项。 我希望内存使用量会随着额外选项的增加而增加,并且会添加此类内容。

也就是说,必须有一些方法来确保您的程序不会耗尽计算机的内存。

所以,我把这个问题变成了一个“最佳实践”问题,询问你们所有人的小技巧和调整是什么,以使您的程序能够以比您通常认为的更少的 CPU 来完成它的工作。还有,最肯定要避免的事情。

这里有个小问题:我在一本关于 C# 的书中偶然发现了一些东西。 显然,在编码 Enum 时,可以设置该 Enum 的索引大小。 对于大型 Enum,我猜你应该让编译器处理它,但是对于只包含 2 或 3 个项目的 Enum,你可以这样做:

public enum HTMLTYPE : sbyte
{
    HTML401,XHTML10,XHTML11
}

对于那些不知道为什么的人,显然为任何 Enum 的索引保留的内存量在 C# 中自动设置为整数。因此,换句话说,将保留该内存量。但是在你的枚举中定义这么少的东西时,整数是浪费空间。 这本书声称这可以减少程序使用的内存量。我想知道这是不是真的。

编辑:确实,它应该是记忆,该死的我。更改了所有条目。

【问题讨论】:

  • 您是否混淆了 CPU 和 RAM(又名内存)?
  • 因此,修复内存泄漏往往会有所帮助。 :)
  • @Bobby:你不能在 C# 中“泄漏”内存。至少在传统意义上,只要你不感到不安全。不过,您可以泄露其他资源。
  • 当然可以在 C#(和 Java)中泄漏内存。只需将内容添加到集合中,然后忘记删除它们。即时内存泄漏。
  • 如果您不再引用该集合,它们将在集合后的某个时间被 GC。如果您引用该集合,则无法 GC 其元素。我没有看到泄漏在哪里......

标签: memory-management


【解决方案1】:

首先,您可能混淆了 CPU 和 RAM(也称为内存)。 CPU 是处理器,即,运行你的代码对你的数据。内存是代码和数据的存储位置

实际上应该避免这种枚举技巧。首先,sbyte 不符合 CLS。然后它可以限制未来的扩张。 CPU 总是使用整个字(int 在 32 位体系结构中和 long 在 64 位体系结构中)的事实总是如此。你失去了这一切,为了什么收获?减少内存占用几个字节。

更重要的是,请遵循这些明智的话:过早的优化是万恶之源。

这意味着,仅在真正需要时才进行优化。首先测量事物。您很可能会意识到需要削减的不是枚举中的那三个字节。

【讨论】:

  • 我赞成这个活动,尽管我对整个“过早优化”的另一个引用有点不知所措!
【解决方案2】:

一种技术是仅在需要时使用lazy initialization 创建对象。

此外,请务必处置(或设置为 null)不再需要的对象,以便对它们进行垃圾回收。

【讨论】:

    【解决方案3】:

    这方面有一本很好的在线书籍:

    http://www.cix.co.uk/~smallmemory/

    【讨论】:

    • 不再可用; this 似乎是同一本书。
    【解决方案4】:

    这是真的,也不是真的。使用 int 是有原因的 - 处理器自然地使用它(除了在运行 x64 Windows 时,更自然的是 Int64)。这是因为在 CPU 中您有 4 个 32 位长(或 x64 模式下为 64 位)的寄存器。

    此外,让我们面对现实:.NET 并不完全注重效率,无论是在内存还是 CPU 方面。有一些做法可以避免犯大错误(比如在循环中连接字符串而不是使用 StringBuilder),但枚举从 4 个字节减少到 1 个字节是不值得的。

    【讨论】:

    • 总的来说,我当然同意。但是,对于非常大的数据集,将存储大小减少 75% 是值得的。 :)
    • 嗯,不。我正在为保险公司开发非常大的应用程序。对一百万个对象的这种优化将给出...... 3 MB。它可能会影响性能。所以最好在其他地方寻找它们。
    【解决方案5】:

    最好的节省内存的方法是先写一段代码干净的方式,这样你就可以在里面看到应用程序的设计了。

    然后制作一个针对内存进行了调整的新版本代码。这样您就可以确保未来的版本不会使用混淆代码。

    是的,随着更好的内存和更少的 CPU,您会考虑进行此类优化。

    【讨论】:

      【解决方案6】:

      所有这些都是解决内存问题的良好算法方法,但在实践中,您还希望通过分析器运行代码以查看内存和 cpu 资源被占用的位置。

      【讨论】:

        【解决方案7】:

        在优化方面,通常最好首先关注算法设计。如果您仍然无法获得所需的性能,那么是时候进行微优化了。

        但免责声明:优化内存使用可能并不总是一件好事。不幸的是,很多时候您必须决定是优化时间(CPU 使用率)还是空间(RAM 或磁盘空间)。虽然有时您也可以吃蛋糕,但并不总是那么简单。

        这里有个小问题:我在一本关于 C# 的书中偶然发现了一些东西。显然,在编码 Enum 时,可以设置该 Enum 的索引大小。对于大型枚举,我猜你应该让编译器处理它,但是对于一个只包含 2 或 3 个项目的枚举,你可以这样做:

        ...

        对于那些不知道为什么的人,显然为任何 Enum 的索引保留的内存量在 C# 中自动设置为整数。因此,换句话说,将保留该内存量。但是在你的枚举中定义这么少的东西时,整数是浪费空间。这本书声称这可以减少程序使用的内存量。我想知道这是不是真的。

        我对此不是 100% 确定,但这可能不一定是真的。事实上,如果您使用 Mono 并将此应用程序部署在其他系统上,那可能不是正确的。原因是不同的操作系统和处理器有不同的内存对齐要求。因此,即使您将其声明为 sbyte,它也可能在它实际进入内存时被强制转换为 32 位或 64 位整数(OS X 对内存对齐特别挑剔)。

        现在,我可能完全错过了这里的重点,而这本书在这种情况下可能是完全正确的。但我在这里的意思更多的是说“它比这更复杂一点”,并指出这种优化可能无法移植到其他平台(不同的操作系统、处理器和编程语言)。

        【讨论】:

        • 实际上,我想说你通常可以吃蛋糕也可以吃。时间与内存权衡是例外;在大多数情况下,更小的内存占用意味着更少的缓存未命中并导致更快的执行速度(有时如此显着)。
        猜你喜欢
        • 1970-01-01
        • 2017-03-04
        • 2010-11-08
        • 1970-01-01
        • 1970-01-01
        • 2014-11-30
        • 2010-11-23
        • 2011-05-14
        • 2018-09-04
        相关资源
        最近更新 更多