循环中的 C# 内存泄漏
本文关键字:内存 泄漏 循环 | 更新日期: 2023-09-27 18:28:46
public void DoPing(object state)
{
string host = state as string;
m_lastPingResult = false;
while (!m_pingThreadShouldStop.WaitOne(250))
{
Ping p = new Ping();
try
{
PingReply reply = p.Send(host, 3000);
if (reply.Status == IPStatus.Success)
{
m_lastPingResult = true;
}
else
{
m_lastPingResult = false;
}
}
catch
{
}
numping = numping + 1;
}
}
知道为什么这段代码给我内存泄漏吗?我可以看到这是这段代码,因为将等待值更改为更小或更大的值会增加内存使用率。有人知道如何解决它吗?或者如何查看代码的哪一部分导致了它?
在某些垃圾回收语言中,存在一个限制,即如果创建对象的方法仍未退出,则不会收集对象。
我相信.net在调试模式下以这种方式工作。引用本文;请注意粗体语句。
http://www.simple-talk.com/dotnet/.net-framework/understanding-garbage-collection-in-.net/
考虑当前正在运行的方法中的局部变量 成为 GC 根。这些变量引用的对象始终可以 通过声明它们的方法立即访问,因此 他们必须留在身边。这些根的寿命可以取决于 程序的构建方式。在调试版本中,局部变量持续存在 只要该方法在堆栈上。在发布版本中,JIT 能够查看程序结构以解决最后一点 在执行中,方法可以使用变量,并且 当不再需要它时,将丢弃它。此策略不是 始终使用并且可以关闭,例如,通过运行程序 在调试器中。
垃圾回收仅在内存压力大时才发生,因此仅看到内存使用量增加并不意味着存在内存泄漏,在此代码中,我看不出如何存在合法泄漏。您可以添加
GC.Collect();
GC.WaitForPendingFinalizers();
仔细检查,但不应该将其留在生产中。
编辑:有人在评论中指出Ping是一次性的。 不调用 dispose 可能会导致泄漏,最终会清理,但可能需要很长时间并导致与内存无关的问题。
在try-catch
中添加一个finally
语句,如下所示:
catch() {}
finally
{
Ping.Dispose();
}
using(var p = new Ping())
{
try
{
var reply = p.Send(host, 3000);
if (reply.Status == IPStatus.Success)
_lastPingResult = true;
else
_lastPingResult = false;
}
catch(Exception e)
{
//...
}
}
这可以从静态类中使用:
public static bool testNet(string pHost, int pTimeout)
{
Ping p = new Ping();
bool isNetOkay = false;
int netTries = 0;
do
{
PingReply reply = p.Send(pHost, pTimeout);
if (reply.Status == IPStatus.Success)
{
isNetOkay = true;
break;
}
netTries++;
} while (netTries < 4);
//Void memory leak
p.Dispose();
return isNetOkay;
}