扫描IP范围后,Garage Collection不会释放内存

时间:2018-02-18 22:03:31

标签: c# memory-management ip ping dispose

我是C#的新手,我正在尝试制作可扫描多个网络的IP扫描仪。我正在构建我的应用程序code

问题是,如果我扫描的网络大于/ 20网络,我会得到OutOfMemoryException:内存不足,无法继续执行程序。扫描大于/ 20的网络需要4GB以上的RAM。

从我可以从谷歌找到的,这是由于Visual Studio只提供4GB的虚拟内存。这不是一个真正的问题,因为它将被部署在一台8GB内存的机器上。

问题是在我扫描网络后,visual studio仍然显示扫描完成后内存正在使用中。

我可以看到车库收集器已从诊断工具窗口运行,但它实际上似乎没有释放太多内存,并且在扫描完成后它不会运行。

这是我的代码。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.NetworkInformation;
using System.Diagnostics;
using System.Net;
using System.Threading;
using System.Net.Sockets;

namespace ConsoleApp2
{
    class Program
    {
        static CountdownEvent countdown;
        static int upCount = 0;
        static object lockObj = new object();
        const bool resolveNames = true;

        public static void Main()        {

            countdown = new CountdownEvent(1);
            Stopwatch sw = new Stopwatch();
            sw.Start();

            //using the 8.8.0.0 /16 as an test network to scan
            string ipBase = "8.8.0.";
            ipBase = ipBase.Substring(0, (ipBase.LastIndexOf(".")));

            ipBase = ipBase.Substring(0, (ipBase.LastIndexOf(".") + 1));

            for (int i = 1; i < 255; i++)
            {
                for (int f = 1; f < 255; f++)
                {
                    string ip = ipBase + i.ToString() + "." + f.ToString();

                    Ping p = new Ping();
                    p.PingCompleted += new PingCompletedEventHandler(p_PingCompleted);
                    countdown.AddCount();
                    // Had to remove the 100ms limit as it would mean i would find less nodes.
                    p.SendAsync(ip, ip); //where i get the exception

                }
            }
            countdown.Signal();
            countdown.Wait();
            sw.Stop();
            TimeSpan span = new TimeSpan(sw.ElapsedTicks);
            Console.WriteLine("Took {0} milliseconds. {1} hosts active.", sw.ElapsedMilliseconds, upCount);
            Console.ReadLine();
        }

        private static void p_PingCompleted(object sender, PingCompletedEventArgs e)
        {
            string ip = (string)e.UserState;
            //Console.WriteLine("{0}", ip);
            if (e.Reply != null && e.Reply.Status == IPStatus.Success)
            {
                if (resolveNames)
                {
                    string name;
                    try
                    {
                        IPHostEntry hostEntry = Dns.GetHostEntry(ip);
                        name = hostEntry.HostName;
                    }
                    catch (SocketException ex)
                    {
                        name = "?";
                    }
                    string s = $"{ip} ({name}) is up: ({e.Reply.RoundtripTime} ms)";
                    Console.WriteLine(s);
                }
                else
                {
                    Console.WriteLine($"{ip} is up: ({e.Reply.RoundtripTime} ms)");
                }
                lock (lockObj)
                {
                    upCount++;
                }
            }
            else if (e.Reply == null)
            {
                Console.WriteLine("Pinging {0} failed. (Null Reply object?)", ip);
            }
            countdown.Signal();
        }


    }
}

为什么即使在扫描完成后内存也没有被释放?

感谢您的帮助。

--- ---更新

public void pingCompleted(object sender, PingCompletedEventArgs e)
        {
            sender.GetType();
            Ping p = ((Ping) sender);
            p.Dispose();
            string ip = (string)e.UserState;
            if (e.Reply != null && e.Reply.Status == IPStatus.Success)
            {
                lock (lockObj)
                {
                    upCount++;
                }
                if (resolveNames)
                {
                    string name;
                    try
                    {
                        IPHostEntry hostEntry = Dns.GetHostEntry(ip);
                        name = hostEntry.HostName;
                    }
                    catch (SocketException ex)
                    {
                        name = Get_Mac_Address(ip);
                        //name = "?";
                    }
                    Console.WriteLine("{0} ({1}) is up: ({2} ms)", ip, name, e.Reply.RoundtripTime);
                    //writeToFile($"Host {upCount} = {ip} ({name}) is up: ({e.Reply.RoundtripTime} ms)");
                }
                else
                {
                    Console.WriteLine("{0} is up: ({1} ms)", ip, e.Reply.RoundtripTime);
                    //writeToFile($"{ip} is up: ({e.Reply.RoundtripTime} ms)");
                }
            }
            else if (e.Reply == null)
            {
                Console.WriteLine("Pinging {0} failed. (Null Reply object?)", ip);
                //writeToFile($"Pinging {ip} failed. (Null Reply object?)");
            }
            p.Dispose();
            countdown.Signal();
        }

0 个答案:

没有答案