简体   繁体   中英

High memory usage for small application

im just building a very simple event based proxy monitor top disable the proxy settings depending on if a network location is available.

the issue is that the application is a tiny 10KB and has minimal interface, but yet it uses 10MB of ram.

The code is pretty simple:

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();
        }
    }
}

My questions are:

  • Is this normal for an application built on C#
  • What can I do to reduce the amount of memory being used.

the application is built on the framework of .NET 4.0

Regards.

It doesn't use anywhere near 10 MB of RAM . It uses 10 MB of address space . Address space usage has (almost) nothing whatsoever to do with RAM.

When you load the .NET framework, space for all the code is reserved in your address space . It is not loaded into RAM. The code is loaded into RAM in 4kb chunks called "pages" on an as-needed basis, but space for those pages has to be reserved in the address space so that the process is guaranteed that there is a space in the address space for all the code it might need.

Furthermore, when each page is loaded into RAM, if you have two .NET applications running at the same time then they share that page of RAM. The memory manager takes care of ensuring that shared code pages are only loaded once into RAM , even if they are in a thousand different address spaces .

If you're going to be measuring memory usage then you need to learn how memory works in a modern operating system . Things have changed since the 286 days.

See this related question:

Is 2 GB really my maximum?

And my article on the subject for a brief introduction to how memory actually works.

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

If you just start your application and then check the amount of memory usage the number may be high. .Net Application preload about 10 MB of memory when the application is started. After your app runs for a while you should see the memory usage drop. Also, just because you see a particular amount of memory in use by your app in the Task Manager it doesn't mean it is using that amount. .Net can also share memory for some components as well as preallocate memory. If you are really concerned get a real profiler for your application.

Your app itself is small, but it references classes the .NET framework. They need to be loaded into memory too. When you use Process Explorer from Sysinternals you can see what dlls are loaded and, if you select some more columns, also how much memory they use. That should help explain where some of the memory footprint is coming from, other reasons as described in the other answers may still be valid.

You could try a GC.Collect() to see how much memory is used after that, not recommended to fiddle with the GC in production code tho.

Regards GJ

Yes this is normal for C# applications, starting the CLR takes some doing. As for reducing this the less DLL's you load the better so see what references you can remove.

Example I see you are importing Linq but did not see any in a quick scan of code, can you remove this and reduce the number of DLL's you project depends on.

I also see that you are using windows forms, 10M is not large for any application using forms.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM