2016-11-15 122 views
1

我想在ASP.NET MVC(5)应用程序中获得关于内存管理的更多信息。MVC应用程序内存管理

为了简单起见,让我们说,我们有角控制器,它不仅使一个http.get()电话对我api controller检索70 000件IEnumerable<CustomItem>,之后将结果输出到页面(页面实现一个简单的页面)。

查看我的诊断工具(内存分析器)时,可以看到内存从50 MB(起始点)上升到300 MB(一旦检索到所有数据)。

这里是我不明白的事情:
为什么当我打开不同的浏览器相同的页面在同一时间(试图模拟更多的用户在同一时间访问该页面),该第二个用户的内存消耗不会再增加250 MB,但即使数据已被再次加载,它仍保持不变?

我在印象中,ApiController不是在用户之间共享,而是为每个用户创建新实例。如果我是对的,情况确实如此,那么如果再有70 000件物品到达内存消费没有改变?

任何文章或解释将不胜感激。

加成1:
我的API控制器被从SharePoint rerieving数据,因此我必须所有70项000记录在一次传递给我的角分量,从而事后实现分页。换句话说,我的组件只加载一次所有数据(70 000条记录),之后只显示一部分(否则,如果我在浏览器用于冻结的70 000个项目上使用了data-ng-repeat)。

如果必要的话我一定能显示我ApiController代码,但实际上它的代码只是3线,返回IEnumerable<CustomItem>仅容纳三个字符串属性。这是它的样子:

public class SharepointFile 
{ 
    public string FileType { get; set; } 
    public string FileName { get; set; } 
    public string FilePath { get; set; } 
} 
+1

您使用的数据库是?你的控制器源代码是什么样的?记录的平均大小是多少?很难说这里发生了什么。大部分的内存使用可能是应用程序本身,而不是数据,但我不确定。 –

+1

需要更多信息,您是否将所有记录加载到内存中?如果分页是以正确的方式实现的(数据库端),那么你从来没有真正拥有'IEnumerable '上的70K记录,你只需要显示(当前页面),并且这不会代表高负载服务器。 – JOBG

+0

从你扔的数字看来,你正在将所有70k记录加载到内存中。对于单个分页查询,内存不应该增加太多。 – user449689

回答

0

您看到的内存上升是进程使用的实际内存。但是如果内存不受先前执行的请求的影响,.NET可能不会分配更多内存,尽管所有对象都将被垃圾回收并将被新分配,但.NET可能不需要更多内存。除非操作系统告知进程,否则通常进程不会释放内存。他们继续使用内存空间。

每次请求后不必要的释放内存将需要大量的CPU使用,它会在操作系统级别在内存中创建大量的碎片。

活动.NET对象的总大小和为它们保留的内存之间总是有区别的。

因此,对于第二个请求,所有70k对象不共享,但它们是新的,但进程已经有空的空间来存储它们,所以它不会从操作系统请求更多的内存。

+0

这是真的吗?在这种情况下,我怎么能告诉我的程序把内存回给操作系统? – user230910

0

你可以让你的ApiController在用户之间共享,但你为什么要这样做?这些mvc应用程序被设置为无状态,并且没有真正需要在请求之间共享它们。

您在内存消耗中看到的内容不与内存中的具体对象匹配。

您可以随时调整应用程序的内存使用情况,以查看正在存储的内容以及分配的内容。您可以尝试Ants Memory ProfilerdotTrace from JetBrains。如果你不能适应其他人的话,那么也有很好的免费WinDbg

另请注意,内存管理主题可能会有所不同,具体取决于您如何托管您的Web应用程序。例如,在IIS中,您会发现与应用程序池的内存管理相关的大量主题。

您可以使用工具资源管理器等工具来比较工作与虚拟内存大小。