无法在c# Winforms中找到内存泄漏
本文关键字:内存 泄漏 Winforms | 更新日期: 2023-09-27 18:15:10
我知道我有内存泄漏。我正在使用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, info传递给数据库,GUI类使用:
发布它。 public void addToTextBox(string s)
{
textBox.Text += s += "'r'n";
textBox.SelectionStart = textBox.TextLength; //scrolling stuff
textBox.ScrollToCaret();
}
Info这样做:
public void takeInGPS(GPS g)
{
gps = g;
write(gps);
}
什么第三方程序会指出内存泄漏在哪里?我每秒创建100个新的GPS对象的事实会是问题吗?我是不是把它们都写掉了?
如果确实存在内存泄漏,您可能必须使用内存分析器来帮助您找到内存泄漏。过去我发现一个很有用的工具是免费的CLR Profiler。您也可以下载它的文档。它将向您展示分配内存的位置,以及每种类型分配了多少内存。它很容易使用。
另一个我在别处见过的是http://memprofiler.com/,但是这个不是免费的(超出试用)
在你的帖子中没有什么真正尖叫"内存泄漏"。进程的内存使用可能由于其他原因而缓慢上升,例如有对象等待垃圾收集。
从你的问题中不清楚有多少数据库访问正在进行,以及在这种情况下"数据库访问"究竟意味着什么。你可能需要确保你的数据库更新发生在一个独立的线程,从一个处理你的UI的东西。虽然可能从UI线程执行数据库调用,但这通常不是一个好主意。这可能就是导致你慢下来的原因。
你还应该确保你的GPS访问也在一个单独的线程从你的UI代码。每秒创建100个新对象不太可能导致内存问题,但请记住,任何访问某种硬件的调用都可能花费比预期更长的时间来处理。
最后一件事……为什么你要每秒读取(或试图读取)GPS设备100次?我想不出任何有意义的场景。据我所知,一个典型的GPS设备每秒只能更新1-5次。更频繁地阅读它并不能提供任何更好的结果。
您是否清除过文本框中的文本,或者只是继续添加它?每次你添加一个长度为M的新条目到下一个盒子,并且它已经有一个长度为N的字符串,它将在执行连接时创建一个长度为N + M的新字符串。如果这个更新非常频繁,并且您从不清除文本框,这将不断累积已分配的内存(其中大部分将符合收集条件,但您仍然会看到内存使用增长。)
要测试这一点,尝试替换文本而不是附加文本,看看这是否会改变您观察到的结果。
我对一个流行问题的回答为您提供了各种分析选项。
如果您使用这些工具,您应该能够找到可疑的内存泄漏发生的位置,并进行代码更改来解决它们。