【问题标题】:Can't find the Memory Leak in C# Winforms [closed]在 C# Winforms 中找不到内存泄漏 [关闭]
【发布时间】:2013-05-24 21:50:37
【问题描述】:

我知道我有内存泄漏。我正在使用 Winforms 用 C# 编写。基本上,我的程序有很多按钮。每 0.01 秒,计时器类调用一个函数以从 gps 获取 gps 数据。每次按下按钮时,它都会与最近的 gps 点配对,并将它们都推送到数据库。我不知道泄漏在哪里。可能与事件处理程序有关吗?每个按钮都有一个+=,但从来没有一个-=。或者当我将 gps 指向 gui 时可能是这样吗?我正在使用实体框架写入数据库。

谢谢,

杰西

编辑: 我知道这是内存泄漏,因为当我进入任务管理器时,我看到我的程序使用的内存一直在增加。此外,计时器不会越频繁地触发,它越晚......从 0.01 秒到大约 0.5 秒。在自动生成的代码中,每个按钮都被订阅(最后一行): this.commentsGoButton.Location = new System.Drawing.Point(348, 23); this.commentsGoButton.Name = "commentsGoButton"; this.commentsGoButton.Size = new System.Drawing.Size(67, 70); this.commentsGoButton.TabIndex = 12; this.commentsGoButton.Text = "Enter Comment"; this.commentsGoButton.UseVisualStyleBackColor = true; this.commentsGoButton.Click += new System.EventHandler(this.commentsGoButton_Click);

另外,我正在调用这个函数:

        GPS gps1 = new GPS(Lat, Longi, Alt, Yaw, Pit, Rol); 
        info.takeInGPS(gps1);
        str = Lat + "   " + Longi + "   " + Alt + "   " + Yaw + "   " + Pit + "   " + Rol + "   ";
        gui.addToTextBox(str);

GPS 是我从中调用它的类。 GPS 是从 GPS 中获取点的类。它由 GUI 类中的计时器调用。 GPS 将其传递给 info 以传递给数据库和 GUI 类以使用:

    public void addToTextBox(string s)
    {
        textBox.Text += s += "\r\n";
        textBox.SelectionStart = textBox.TextLength; //scrolling stuff
        textBox.ScrollToCaret();
    }

信息是这样的:

public void takeInGPS(GPS g) { gps = g; write(gps); }

哪些第 3 方程序会指出内存泄漏的位置?我每秒创建 100 个新 GPS 对象这一事实是否会成为问题?我不是要覆盖它们吗?

【问题讨论】:

  • 是的,它可以是任何地方。您可以通过调试来检查这一点。没有代码,我无法为您提供更多信息。
  • 一些您认为问题所在的示例代码可能会有所帮助。
  • 您是否在积极地使用using 语句来处理对象?
  • 我建议使用内存分析器 - 它应该有助于说明问题。
  • I know that I have a memory leak。您是如何得出这个结论的?

标签: c# winforms memory-leaks


【解决方案1】:

如果确实存在内存泄漏,您可能必须使用内存分析器来帮助您找到内存泄漏。我过去发现其中一个有用的工具是免费的CLR Profiler。你也可以下载它的documentation。它将为您提供内存分配位置的图片,以及每种类型分配了多少内存。它很容易使用。

我在其他地方看到的另一个是http://memprofiler.com/,但那个不是免费的(试用版除外)。

【讨论】:

【解决方案2】:

您的帖子中没有任何内容真正尖叫“内存泄漏”。进程的内存使用量可能会因为其他原因而增加,例如让对象等待垃圾回收。

从您的问题中不清楚有多少数据库访问正在进行,以及在这种情况下“数据库访问”究竟意味着什么。您可能需要确保您的数据库更新发生在与处理您的 UI 内容的线程不同的线程中。虽然可能从您的 UI 线程进行数据库调用,但这通常不是一个好主意。这可能是导致您速度变慢的原因。

您还应该确保您的 GPS 访问也位于与您的 UI 代码不同的线程中。每秒创建 100 个新对象不太可能导致内存问题,但请记住,任何访问某种硬件的调用可能需要比您预期的更长的时间来处理。

最后一件事...为什么您要每秒读取(或尝试) 100 次 GPS 设备?我想不出任何有意义的场景。据我所知,典型的 GPS 设备每秒仅更新 1-5 次。更频繁地阅读它并不会提供更好的结果。

【讨论】:

  • 我正在描绘一条道路。实际上,10-20Hz 就可以了。我对线程不熟悉...问题仅在 10 分钟后发生。
【解决方案3】:

您是否曾经清除文本框中的文本,还是只是继续追加?每次你将一个长度为 M 的新条目添加到下一个框并且它已经有一个长度为 N 的字符串时,它会在执行连接时创建一个长度为 N + M 的新字符串。如果此更新非常频繁并且您从不清除文本框,这将不断累积分配的内存(其中大部分将符合收集条件,但您仍会看到内存使用量增加。)

要对此进行测试,请尝试替换文本而不是附加文本,看看这是否会改变您观察到的结果。

【讨论】:

  • 这极大地减少了内存使用量的增长。它仍在增长,但速度要慢得多...感谢您的想法。
【解决方案4】:

我的answerpopular question 为您提供各种分析选项。

如果您使用这些工具,您应该能够找到您怀疑发生内存泄漏的位置并更改代码以解决这些问题。

【讨论】:

    猜你喜欢
    • 2017-11-14
    • 2020-09-18
    • 1970-01-01
    • 2011-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-05
    相关资源
    最近更新 更多