我只是构建一个非常简单的基于事件的代理监视器,根据网络位置是否可用,禁用代理设置。
问题是应用程序是一个10KB的小应用程序,界面很少,但它使用10MB内存。
代码非常简单:
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();
}
}
}
我的问题是:
该应用程序构建于.NET 4.0的框架
之上问候。
答案 0 :(得分:8)
它不会在10 MB RAM 附近使用。它使用10 MB 地址空间。地址空间使用(几乎)与RAM无关。
加载.NET框架时,地址空间中所有代码的空间保留。它没有加载到RAM中。代码根据需要以4kb块的形式加载到RAM中,但这些页面的空间必须保留在地址空间中,以便保证进程可以在地址空间中留出空间,以获取它可能需要的所有代码。
此外,当每个页面 加载到RAM中时,如果您同时运行两个.NET应用程序,那么它们共享该RAM页面。内存管理器负责确保共享代码页只加载一次 RAM ,即使它们位于千个不同的地址空间中。
如果您要测量内存使用情况,那么您需要了解内存在现代操作系统中的工作原理。自286天以来情况发生了变化。
请参阅此相关问题:
关于这个主题的文章,简要介绍了记忆的实际运作方式。
答案 1 :(得分:1)
如果您刚刚启动应用程序,然后检查内存使用量,则该数字可能很高。 .Net应用程序在应用程序启动时预加载大约10 MB的内存。应用程序运行一段时间后,您应该看到内存使用量下降。此外,仅仅因为您在任务管理器中看到应用程序正在使用的特定内存量,并不意味着它正在使用该数量。 .Net还可以共享某些组件的内存以及预分配内存。如果您真的担心为您的应用程序获得一个真正的分析器。
答案 2 :(得分:1)
您的应用程序本身很小,但它引用了.NET框架类。它们也需要加载到内存中。当您使用Process Explorer from Sysinternals时,您可以看到加载了哪些dll,如果您选择了更多列,还会看到它们使用了多少内存。这应该有助于解释某些内存占用的来源,其他答案中描述的其他原因可能仍然有效。
您可以尝试使用GC.Collect()
来查看之后使用了多少内存,不建议在生产代码中使用GC。
关心GJ
答案 3 :(得分:0)
是的,对于C#应用程序来说这是正常的,启动CLR需要做一些事情。 至于减少这个,你加载的DLL越少越好,所以看看你可以删除哪些引用。
示例我看到您正在导入Linq,但在快速扫描代码时没有看到任何内容,您是否可以删除它并减少项目所依赖的DLL数量。
我也看到你正在使用Windows窗体,对于使用表单的任何应用程序,10M都不大。