简体   繁体   English

小应用程序的高内存使用率

[英]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. 问题是该应用程序是一个小的10KB,并具有最小的接口,但它使用10MB的内存。

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# 对于基于C#构建的应用程序,这是正常的吗
  • What can I do to reduce the amount of memory being used. 我该怎么做才能减少使用的内存量。

the application is built on the framework of .NET 4.0 该应用程序构建于.NET 4.0的框架之上

Regards. 问候。

It doesn't use anywhere near 10 MB of RAM . 它不使用任何接近10 MB的RAM It uses 10 MB of address space . 它使用10 MB的地址空间 Address space usage has (almost) nothing whatsoever to do with RAM. 地址空间使用(几乎)与RAM无关。

When you load the .NET framework, space for all the code is reserved in your address space . 加载.NET框架时,所有代码的空间都保留地址空间中 It is not loaded into RAM. 它没有加载到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. 代码根据需要以4kb块的形式加载到RAM中,但必须在地址空间中 保留这些页面的空间 ,以确保进程在地址空间中有一个空间供所有人使用。它可能需要的代码。

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. 此外,当每个页面加载到RAM中,如果你有在同一时间运行两个.NET应用程序,然后他们分享的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 . 内存管理器负责确保共享代码页只加载一次到RAM中 ,即使它们位于千个不同的地址空间中

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. 事情发生了变化,自286天以来。

See this related question: 看到这个相关的问题:

Is 2 GB really my maximum? 2 GB真的是我最大的吗?

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 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. .Net应用程序在应用程序启动时预加载大约10 MB的内存。 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. .Net还可以共享某些组件的内存以及预分配内存。 If you are really concerned get a real profiler for your application. 如果你真的担心为你的应用程序获得一个真正的分析器。

Your app itself is small, but it references classes the .NET framework. 您的应用程序本身很小,但它引用.NET框架类。 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. 当您使用Sysinternals中的Process Explorer时,您可以看到加载了哪些dll,如果您选择了更多列,那么它们还会使用多少内存。 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. 您可以尝试使用GC.Collect()来查看之后使用了多少内存,不建议在生产代码中使用GC。

Regards GJ 关心GJ

Yes this is normal for C# applications, starting the CLR takes some doing. 是的,对于C#应用程序来说这是正常的,启动CLR需要做一些事情。 As for reducing this the less DLL's you load the better so see what references you can remove. 至于减少这个,你加载的DLL越少越好,所以看看你可以删除哪些引用。

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. 示例我看到您正在导入Linq但在快速扫描代码时没有看到任何内容,您是否可以删除它并减少项目依赖的DLL数量。

I also see that you are using windows forms, 10M is not large for any application using forms. 我也看到你使用的是Windows窗体,对于使用表单的任何应用程序,10M并不大。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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