Высокое использование памяти для небольших приложений - PullRequest
3 голосов
/ 21 марта 2011

я просто строю очень простой событийный прокси-монитор. Отключите настройки прокси-сервера в зависимости от того, доступно ли сетевое расположение.

проблема в том, что приложение имеет крошечные 10 КБ и имеет минимальный интерфейс, но все жеон использует 10 МБ оперативной памяти.

Код довольно прост:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.NetworkInformation;
using Microsoft.Win32;

namespace WCSProxyMonitor
{
    class _Application : ApplicationContext
    {
        private NotifyIcon NotificationIcon = new NotifyIcon();
        private string IPAdressToCheck = "10.222.62.5";

        public _Application(string[] args)
        {
            if (args.Length > 0) 
            {
                try
                {
                    IPAddress.Parse(args[0]); //?FormatException
                    this.IPAdressToCheck = args[0];
                }
                catch (Exception) 
                {}
            }

            this.enableGUIAspects();
            this.buildNotificationContextmenu();
            this.startListening();
        }

        private void startListening() 
        {
            NetworkChange.NetworkAddressChanged += new NetworkAddressChangedEventHandler(networkChangeListener);
        }

        public void networkChangeListener(object sender, EventArgs e)
        {
            //foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
            //{
                //IPInterfaceProperties IPInterfaceProperties = nic.GetIPProperties();
            //}

            //Attempt to ping the domain!
            PingOptions PingOptions = new PingOptions(128, true);
            Ping ping = new Ping();

            //empty buffer
            byte[] Packet = new byte[32];

            //Send
            PingReply PingReply = ping.Send(IPAddress.Parse(this.IPAdressToCheck), 1000, Packet, PingOptions);

            //Get the registry object ready.
            using (RegistryKey RegistryObject = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", true)) 
            {
                if (PingReply.Status == IPStatus.Success)
                {
                    this.NotificationIcon.ShowBalloonTip(3000, "Proxy Status", "proxy settings have been enabled", ToolTipIcon.Info);
                    RegistryObject.SetValue("ProxyEnable", 1, RegistryValueKind.DWord);
                }
                else
                {
                    this.NotificationIcon.ShowBalloonTip(3000, "Proxy Status", "proxy settings have been disabled", ToolTipIcon.Info);
                    RegistryObject.SetValue("ProxyEnable", 0, RegistryValueKind.DWord);
                }
            }
        }

        private void enableGUIAspects()
        {
            this.NotificationIcon.Icon = Resources.proxyicon;
            this.NotificationIcon.Visible = true;
        }

        private void buildNotificationContextmenu()
        {
            this.NotificationIcon.ContextMenu = new ContextMenu();
            this.NotificationIcon.Text = "Monitoring for " + this.IPAdressToCheck;

            //Exit comes first:
           this.NotificationIcon.ContextMenu.MenuItems.Add(new MenuItem("Exit",this.ExitApplication));
        }

        public void ExitApplication(object Sender, EventArgs e)
        {
            Application.Exit();
        }
    }
}

Мои вопросы:

  • Это нормально для приложения, построенного на C #
  • Что можно сделать, чтобы уменьшить объем используемой памяти.

приложение построено на основе .NET 4.0

С уважением.

Ответы [ 4 ]

8 голосов
/ 21 марта 2011

Он не использует около 10 МБ RAM . Он использует 10 МБ адресного пространства . Использование адресного пространства не имеет (почти) никакого отношения к оперативной памяти.

Когда вы загружаете .NET Framework, пространство для всего кода зарезервировано в вашем адресном пространстве . Он не загружен в оперативную память. Код загружается в ОЗУ порциями по 4 КБ, которые называются «страницами» по мере необходимости, но пространство для этих страниц должно быть зарезервировано в адресном пространстве , чтобы процесс Гарантируется, что в адресном пространстве есть пробел *1016* для всего кода, который может понадобиться.

Кроме того, когда каждая страница загружается в ОЗУ , если у вас одновременно запущены два приложения .NET, они совместно используют эту страницу ОЗУ. Диспетчер памяти заботится о том, чтобы совместно используемые кодовые страницы загружались только один раз в RAM , даже если они находятся в тысяче различных адресных пространств .

Если вы собираетесь измерять использование памяти, тогда вам нужно узнать, как работает память в современной операционной системе . С 286 дней все изменилось.

Смотрите этот вопрос по теме:

Действительно ли 2 ГБ - мой максимум?

И моя статья на эту тему для краткого введения в то, как на самом деле работает память.

http://blogs.msdn.com/b/ericlippert/archive/2009/06/08/out-of-memory-does-not-refer-to-physical-memory.aspx

1 голос
/ 21 марта 2011

Если вы просто запустите свое приложение, а затем проверьте объем использования памяти, это число может быть высоким. Приложение .Net предварительно загружает около 10 МБ памяти при запуске приложения. После того, как ваше приложение запустится некоторое время, вы увидите падение использования памяти. Кроме того, только потому, что вы видите определенный объем памяти, используемый вашим приложением в диспетчере задач, это не означает, что он использует этот объем. .Net также может совместно использовать память для некоторых компонентов, а также предварительно выделять память. Если вы действительно обеспокоены, получите реальный профилировщик для вашего приложения.

1 голос
/ 21 марта 2011

Само ваше приложение маленькое, но оно ссылается на классы .NET Framework.Их тоже нужно загрузить в память.Когда вы используете Process Explorer из Sysinternals , вы можете видеть, какие библиотеки загружены, и, если вы выберете еще несколько столбцов, а также объем памяти, который они используют.Это должно помочь объяснить, откуда берутся некоторые следы памяти, другие причины, описанные в других ответах, все еще могут быть действительными.

Вы можете попробовать GC.Collect(), чтобы увидеть, сколько памяти используется после этого, не рекомендуется возиться с GC в рабочем коде tho.

С уважением, GJ

0 голосов
/ 21 марта 2011

Да, это нормально для приложений C #, для запуска CLR требуется некоторое время.Что касается уменьшения этого, чем меньше DLL вы загружаете, тем лучше, поэтому посмотрите, какие ссылки вы можете удалить.

Пример. Я вижу, что вы импортируете Linq, но не нашли ничего в быстром сканировании кода, можете ли вы удалить его и уменьшить количество DLL, от которых зависит ваш проект.

Я также вижу, чтоВы используете формы Windows, 10M невелик для любого приложения, использующего формы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...