.NET EXE内存占用

23
即使是一个简单的 C# 记事本 应用程序,在任务管理器中也会消耗几兆字节的 RAM。当最小化应用程序时,任务管理器中的内存大小会显著降低,并在应用程序最大化时重新上升。
我在某个地方读到过,.NET 进程在运行时分配时提前保留了大量内存。这就是为什么 .NET 应用程序一开始就具有较大的内存占用。但是可以使用 Win32 API 调用释放这些内存。权衡之处在于运行时分配变慢 - 这是真的吗?
3个回答

37

内存占用较大的原因是JIT编译器和 Windows Forms 引擎正在与您的进程一起加载。为了减少内存占用,您可以采取以下措施:


The reason for the large memory footprint is that the JIT compiler and Windows Forms engine are being loaded with your process. To reduce this, you can do the following:
[DllImport("psapi.dll")]
static extern int EmptyWorkingSet(IntPtr hwProc);

static void MinimizeFootprint()
{
    EmptyWorkingSet(Process.GetCurrentProcess().Handle);
}

这应该尽可能从您的内存占用中移除。也许还有一种方法,可以减少为运行时内存分配所保留的内存量。


3
我想对此表示感谢,并补充一点说明。我知道工作集并不是一个有效的表示方式,但是这个数字经常会吓到管理员。这个技巧让我正在开发中的一个应用程序的工作集从平均80-120兆减少到了20-40兆。赞一个。 - John Rudy
1
dotnetcoder-- 这种权衡是,如果您的应用程序需要您释放的任何资源,那么您将会遇到性能损失,这种情况相对较常见。 - Ed Altorfer
John Rudy--我知道那是什么感觉;有人看到你的应用程序占据了“大量空间”,就会感到恐慌。我很高兴这能为你提供一些帮助。 :) - Ed Altorfer
我认为:让Windows处理工作集大小。强制它将所有内容写入页面文件对性能不利。同样的道理,你也不应该强制进行垃圾回收。要教育那些根据工作集大小认为你的应用程序占用了太多内存的人。 - Lars Truijens
7
好主意,只需教育全世界,特别是软件评论员。这是一个实际的解决方案。或者也许不是。似乎更好的做法是接受(可能无法察觉的)性能损失。 - mhenry1384
mhenry1384,我认为Lars的意思是开发人员帮助重新教育那些认为80-120 mb的工作集太大的系统管理员会很有帮助。在许多情况下,这可能既实用又有建设性。 - Ed Altorfer

29

不应使用TaskManager来测量.NET应用程序的内存占用。

当一个.NET应用程序启动时,它会向操作系统请求一块内存,然后将其分割为受控堆、堆栈和大对象堆。TaskManager报告的是这个总内存块,可能完全被.NET使用或未被完全使用。一旦.NET应用程序获得了一块内存,它不会释放它,除非操作系统要求释放,只有在操作系统确定需要更多内存资源时才会发生。

如果您想测量内存分配情况,需要查看各种性能监视器(PerfMon)计数器。

您可以使用Interop代码调用Win32 API来修剪您的工作集大小,但下次应用程序请求操作系统内存时,工作集将重新增加,并且在操作系统分配并提供额外内存并且.NET运行时“配置”它时,会出现性能影响。


3

任务管理器无法显示.NET应用程序的实际内存使用情况。要查看这一点,您几乎必须在应用程序上放置性能计数器或使用分析器。

在任务管理器中看到的是应用程序的工作内存,其中包括框架本身的许多开销,在您的应用程序加载时也必须加载。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接