当我运行我的应用程序时,在一个分析器中,我看到它使用了大约80MB的内存(总提交字节数,性能计数器)。但是,当我查看分配内存的大小时,它超过400MB!
所以我的问题是,为什么.NET为我的应用程序保留了这么多内存?这是正常的吗?
答案 0 :(得分:7)
你应该阅读Memory Mystery。我前一段时间遇到过类似的问题,在读完之后就不再问自己了。 我读了其他消息来源,但我现在找不到,使用关键词“无理分配内存窗口操作系统”。简而言之,根据物理上可用的内存资源,操作系统提供的功能超出了应用程序的要求 例如如果您在具有不同RAM的两台计算机上运行您的应用程序,则可以保证这两台计算机将具有不同的内存分配
答案 1 :(得分:1)
毫无疑问,正如使用和分配的实际内存之间存在巨大差异。应用程序分配的内存并不意味着它实际上在任何地方使用;它真正意味着操作系统已经“标记”了一个虚拟内存区域(正好是虚拟内存),可供应用程序使用。
内存不一定被使用或者在其他进程中挨饿 - 如果应用程序开始填充内存,它只是 。
此分配的数字也可能根据机器的整体内存生态系统进行扩展。如果一个应用程序启动时有足够的空间,那么它可能会获得比没有更少的更多的分配。
该原则与创建List<T>
的良好做法相同,例如,具有合理的初始容量,这意味着可以在调整大小之前添加相当数量的项目。操作系统在内存使用方面采用相同的方法。
答案 2 :(得分:0)
“保留”记忆与“已分配”的内存绝不相同。阅读Steve和Krishna所关联的帖子。
您的客户需要查看的部分是Private Bytes。但即使这也不是一个很难的数字,因为您的应用程序的某些部分可能会被交换到虚拟磁盘。
简而言之,除非您的私有字节部分完全失控或者您有泄漏(即:未处置的非托管资源),您(和您的客户端)应该忽略这一点并让操作系统管理分配的内容,物理内存中的内容什么被换成了磁盘。
答案 3 :(得分:0)
软件向底层操作系统发出一个大内存请求,然后在内部管理自己对已分配内存块的使用,这是很常见的。事实上,Windows(和其他操作系统)内存管理器明确地支持这个概念,称为“未提交的内存” - 该进程已请求但尚未使用的内存。该存储器确实不存在存在,只要占用DRAM芯片上的空间,直到该过程实际使用它为止。预先分配内存实际上没有任何成本。
应用程序执行此操作有很多原因 - 尽管它主要是出于性能原因而完成的。具有自己的内存使用模式知识的应用程序可以优化其针对该模式的分配器;类似地,出于地址局部性的原因,来自OS的连续内存请求在内存中并不总是彼此“下一步”,这可能会影响CPU缓存的性能,甚至可能使您无法使用某些优化。
由于上面列出的两个原因,.NET特别提前为托管堆分配空间。在大多数情况下,在托管堆上分配内存仅涉及增加堆顶部指针,这非常快 - 而且标准内存分配器也无法实现(它具有更通用的设计,可以在分段中执行堆,而CLR的GC使用内存压缩来严格限制托管堆的碎片),如果托管堆本身由于在不同时间点的多次分配而在整个进程地址空间中碎片化,也是不可能的。