日期:2014-05-18  浏览次数:20916 次

C# ping 类的内存泄露问题
代码如下:

public class MyPing : Ping
{
    public void PingCompletedCallBack(object sender, PingCompletedEventArgs e)
 
    {
        
        using (sender as Ping) 
       {
        
           if (e.Reply.Status == IPStatus.Success)
   
           {
        
               Console.WriteLine("Address: {0}", e.Reply.Address.ToString());
   
           }
      
        }
        (sender as IDisposable).Dispose();
   
     }
}
   
class Program
  
{
      
  static void Main(string[] args)
   
  {
        
    string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
   
    byte[] buffer = Encoding.ASCII.GetBytes(data);
   
    int timeout = 1000;
      
    for (int j = 0; j< 1000; j++)
   
    {
           
       for (int i = 0; i < 1000; i++)
    
       {
               
          MyPing pingSender = new MyPing();
    
          try
           
          {
              pingSender.PingCompleted += new PingCompletedEventHandler(pingSender.PingCompletedCallBack);
              pingSender.SendAsync(args[0], timeout, buffer, null);
 
          }
        
          catch ( Exception )
              
          {
                     
              ((IDisposable)pingSender).Dispose();
         
          }
          
       }
         
    }
        
  }
  
}
运行的系统为win7
现象是内存不断增长,最后出现内存耗尽,出现异常。
以下的这个帖子我已经看过,就是按照上面的说法使用了using 语句,可是问题依旧。
http://www.cnblogs.com/Gildor/archive/2009/09/08/1562225.html?login=1#commentform
在资源管理器中看多句柄数不断增长,可能还是内部有非托管资源没有回收导致的。
谁还有解决办法?



------解决方案--------------------
我能怎么说你呢?这哪里是内存泄漏啊,这其实是你并发开太多造成的。SendAsync是异步执行的方法,你一个100万次的循环里,一瞬间开了100万个并发操作,系统资源能足够吗?
------解决方案--------------------
pingSender.SendAsync是异步调用托管线程池线程来执行的,当可用线程用完时,将排队。
对于LZ千万级的实例,系统除了每个线程都要进入Ping等待返回,另一方面还需要维护这个队列,也许CPU占用并不会太高,但是系统能使用的TCP连接/半连接数是有限的,远远小于并发线程数

自己想想吧
------解决方案--------------------
探讨

引用:

一口气吃1000000包子的问题,不管泄露的事,重设计控制并发量


我只是有点较真想找出为啥就吃不了1000000包子(因为理论上来说,缓存1000000个包子根本就不是问题)