2012-03-12 88 views
5

当我运行我的应用程序时,在一个探查器中,我看到使用了大约80MB的内存(总提交字节数,性能计数器)。但是当我查看分配内存的大小时,它已超过400MB!为什么.NET为我的应用程序保留这么多内存?

所以我的问题是,为什么.NET为我的应用程序保留这么多内存?这是正常的吗?

+1

你的机器有多少内存? – 2012-03-12 15:37:46

+0

这是无关紧要的。我的客户为其用户提供了最大200MB的限制。除此之外,我只想知道为什么.NET会这么做,或者为什么它如此之多:) – Martijn 2012-03-12 15:39:28

+0

[这篇文章非常有用](http://www.itwriting.com/dotnetmem.php) – Steve 2012-03-12 15:46:35

回答

1

正如你毫无疑问知道,使用和分配的实际内存之间存在巨大差异。应用程序分配的内存并不意味着它实际上在任何地方使用;所有这一切意味着操作系统已经标记了一个虚拟内存区域(这正是虚拟内存),可供应用程序使用。

内存不一定在使用或挨饿其他进程 - 它只是可能如果应用程序开始填充它。

这个分配数量,也将根据机器的整体记忆的生态系统可能规模。如果应用程序启动时有足够的空间,那么它可能会占用较大的分配空间,而不是较少。

这个原理与创建List<T>是一个很好的实践是一样的,比如说,具有合理的初始容量,这意味着在调整大小需要发生之前可以添加相当数量的项目。操作系统采用与内存使用相同的方法。

+0

这的确是我已经知道的,但无论如何感谢。但我仍然很好奇为什么.NET保留了这么多的内存。如果它大概在40MB左右,好吧,但我认为320MB非常棒! – Martijn 2012-03-12 15:49:18

+3

这不仅仅是.Net,操作系统在内存预留中扮演着重要角色。基本上,windows说:“我有16GB的物理内存,我想我会为这个过程分配1GB ...”**对于完全相同的应用程序,*不同的机器***,它可能会说“我有4GB物理RAM,我将为这个过程分配200MB ......“这两个都没有提到你的应用程序,.net框架或其他任何东西。 – NotMe 2012-03-12 15:55:03

6

你应该阅读Memory Mystery。我刚才也有类似的问题,读完这些后我不再问自己。 我读了其他来源,但我现在找不到,使用关键字“不合理的内存窗口操作系统分配”。简而言之,操作系统提供的应用程序数量超过了您的应用程序的要求,具体取决于物理可用内存资源 ,例如,如果你在两台机器上用不同的RAM运行你的应用程序,它可以保证这两个机器都会有不同的内存分配

+1

链接已损坏。 – Dan 2012-12-20 14:56:19

+1

http://www.onlingguns.com/forum/threads/88-The-Memory-Mystery – 2015-06-29 01:12:20

+0

感谢Van Thoai Nguyen - 更新了现在的链接 – Krishna 2015-06-29 07:10:45

0

“预留”的内存绝不等同于“分配”公羊。阅读Steve和Krishna的帖子。

你的客户需要看的部分是私人字节。但即便如此,也不完全是一个硬数字,因为您的应用程序的某些部分可能会交换到虚拟磁盘。你的(和你的客户)应该忽略这一点,并让操作系统管理分配的内容,物理内容是什么,如果你的私人字节部分已经完全失去控制或者你有泄漏(即:未处理的非托管资源)内存和什么交换到磁盘。

0

这是相当常见的软件发出一个大的内存请求底层操作系统,然后在内部管理自己使用分配的内存块的。实际上,Windows(和其他操作系统)的内存管理器实际上很常见,它明确支持这个称为“未提交内存”的概念,即该进程请求但尚未使用的内存。该内存真的不存在只要位占用DRAM芯片上的空间,直到该过程实际使用它。内存的预分配实际上不需要任何费用。

应用程序出于多种原因执行此操作 - 尽管它主要是出于性能原因而完成的。具有其自己的内存使用模式知识的应用程序可以针对该模式优化其分配器;同样,由于地址本地原因,因为来自操作系统的连续内存请求并不总是在内存中相互“接近”,这可能会影响CPU高速缓存的性能,甚至可能会妨碍您使用某些优化。

由于上述两个原因,.NET特别为托管堆提前分配空间。在大多数情况下,在托管堆上分配内存仅涉及递增堆顶指针,这是非常快的 - 而且也不可能使用标准内存分配器(其具有更通用的设计以在碎片中可接受地执行堆,而CLR的GC使用内存压缩来急剧限制托管堆的碎片),而且如果由于在不同时间点的多个分配而导致托管堆本身在进程地址空间中被分段,则也不可能。

相关问题