代码之家  ›  专栏  ›  技术社区  ›  Jeremiah

解决C语言中内存泄漏的方法有哪些#

  •  10
  • Jeremiah  · 技术社区  · 16 年前

    我在学C。据我所知,您必须正确设置,让垃圾收集器实际删除所有应该删除的内容。我在寻找多年来从你身上学到的智慧,聪明的人。

    我来自C++背景,非常习惯于代码和开发模式。我想了解C#中的代码味道。给我建议!

    删除内容的最佳方法是什么?


    编辑:我正在尝试制定一份“内存管理需要经常做的事情”的剩余工作清单


    10 回复  |  直到 10 年前
        1
  •  18
  •   Samuel    16 年前

    NET Framework使用托管内存,所有内容(除了分配的非托管资源)都被垃圾收集。

    arrays , classes structures . 随便做 int[] stuff = new int[32]; 忘了它吧。

    如果在类中打开文件、数据库连接或任何其他非托管资源,请实现IDisposable接口,并在Dispose方法中取消分配非托管资源。

    任何实现IDisposable的类都应该显式关闭,或者使用类似块的方法(我认为很酷)使用;

    using (StreamReader reader = new StreamReader("myfile.txt"))
    {
       ... your code here
    }
    

        2
  •  11
  •   Marc Gravell    16 年前

    GC的第一件事是它是不确定的;如果您希望及时清理资源,请实施 IDisposable using ; 这不会收集托管内存,但对非托管资源和后续链有很大帮助。

    • 大量固定(对GC的功能有很多限制)
    • 很多终结器(您通常不需要它们;降低GC的速度)
    • 在廉价长寿命对象上的事件,可以看到本应清理的昂贵对象
    • “捕获变量”意外地使图形保持活动状态

    用于调查内存泄漏。。。“SOS”是最简单的路线之一;您可以使用SOS查找类型的所有实例,以及可以看到的内容,等等。

        3
  •  3
  •   Michael Meadows    16 年前

    一般来说,在C#中,您越不担心内存分配,您的情况就越好。当我在收集方面遇到问题时,我会让档案员告诉我。

    • 了解收集的频率(出于性能原因)
    • 对对象的引用保留的时间不要超过需要的时间
    • 处理完实现IDisposable的对象后,立即将其丢弃(使用 using (语法)
    • IDisposable interface
        4
  •  3
  •   Grzenio    16 年前

    我能想到的内存泄漏的主要来源是:

    • 保留对不再需要的对象的引用(通常是在某种类型的集合中),因此这里您需要记住,添加到集合中的所有引用也将保留在内存中。

    • 具有循环引用,例如让代表在活动中注册。因此,即使您显式地不引用对象,也无法对其进行垃圾收集,因为它的一个方法已注册为带有事件的委托。在这些情况下,您需要记住在放弃引用之前删除委托。

    • 与本机代码互操作但未能释放本机代码。即使使用实现终结器的托管包装器,CLR通常也不会足够快地清理它们,因为它不了解内存占用。您应该使用using(IDisposable){}模式
        5
  •  1
  •   Matt Weyland Matt Weyland    16 年前

    内存管理需要考虑的另一件事情是,如果您正在实现任何观察者模式,而不是正确地处理引用。

    对象A监视对象B 对象B被释放如果从A到B的引用未被释放,则GC将不会正确地释放该对象。由于事件处理程序仍然被分配,GC不会将其视为未使用的资源。

    如果你有一小组你正在使用的对象,这可能与我无关。但是,如果您使用数千个对象,这可能会在应用程序的整个生命周期中导致内存逐渐增加。

        6
  •  1
  •   Konstantin Tarkus    16 年前

    我建议使用 .NET Memory Profiler

    .NET内存探查器将帮助您:

    • 查看实时内存和资源信息
    • 通过收集和比较.NET内存快照,轻松识别内存泄漏
    • 查找未正确处理的实例
    • 获取有关非托管资源使用情况的详细信息
    • 优化内存使用
    • 调查生产代码中的内存问题
    • 执行自动内存测试
    • 检索有关本机内存的信息

    看看他们的视频教程:

    http://memprofiler.com/tutorials/

        7
  •  1
  •   user83254 user83254    16 年前

    我想建议一些额外的资源;在学习.NET GC的细节以及如何解决.NET应用程序中的内存问题时,我发现以下内容非常有价值。

    CLR via C# 杰弗里·里克特是一位 书仅就GC和内存这一章而言,这是值得购买的价格。

    blog (由一位Microsoft“ASP.NET升级工程师编写)经常是我获取有关使用WinDbg、SOS和发现某些类型内存泄漏的提示和技巧的来源。Tess甚至设计了.NET调试演示/实验室,它将引导您了解常见的内存问题以及如何识别和解决这些问题。

    Debugging Tools for Windows

        8
  •  0
  •   Roman Motyka James Nugent    16 年前

    CLR profiler 学习如何正确使用它需要一些时间,但毕竟它是免费的。(它多次帮助我发现内存泄漏)

        9
  •  0
  •   Cecil Has a Name    16 年前

    确保对象被删除或在.NET行话中被垃圾收集的最佳方法是确保对象的所有根引用(可通过方法和对象跟踪到线程调用堆栈上第一个方法的引用)都设置为null。

    循环引用不会造成惩罚或内存泄漏的可能性,因为GC会在对象图中标记它访问过的对象。在委托或事件处理程序的情况下,通常会忘记删除事件中对目标方法的引用,因此如果事件是根事件,则无法收集包含目标方法的对象。

        10
  •  0
  •   Judah Gabriel Himango    16 年前

    删除内容的最佳方法是什么?

    注意:以下仅适用于包含非托管资源的类型。它对纯托管类型没有帮助。