我们有几个使用ASP.NET和DevExpress ASPxGridView组件的不同项目。在这些项目的开发过程中,已经使用了几种数据绑定技术,我们现在发现其中一些项目占用了服务器上的所有内存。
最初,我们使用对存储过程的调用并将DataSet绑定到gridview,但是在DX建议中,将其修改为ObjectDataSource并创建了最终对数据库使用Linq语句并返回泛型的对象然后绑定的对象列表。
不幸的是,这并不能解决手头的问题。我们仍然注意到大量的内存被吃掉了,我正试图找到它的底部。当通过RedGate内存分析器运行时,我注意到每次重新绑定到网格时都会创建很多字符串,RuntimeTypeHandles和我的对象实例。
DataBind是在页面加载时完成的,并且网格在排序时使用回发,但这会导致每个绑定都会泄漏内存的MB,所以我想知道我可以使用哪些技术/管理对象的最佳实践有控制权吗?我已经在数据对象中实现了IDisposable,处理了linq上下文并将任何其他对象设置为null,但它似乎没有什么区别。我似乎在每次调用时都在创建数据对象的实例,甚至调用dispose也没什么区别。
答案 0 :(得分:2)
是否有可能缩小范围?也就是说,你可以从页面上删除东西,看看它的表现如何?
原谅这一点,但当你说'泄漏记忆'时,你是什么意思,你怎么知道? GC是“懒惰的”,在有压力之前不会做任何事情。这是一件好事,但它也意味着在需要集合之前,内存可能会累积,然后您可能会发现它可以释放很多东西。由于这个原因,记忆分析器通常看起来像锯齿。
如何存储网格数据以使分页工作?我已经看到数据集在视图状态中持久存在,这意味着数据与网格一起传递给客户端。如果你再次查询后页面加载,那你就会浪费很多空间。
另一个常见问题是事件订阅使大对象保持活动的时间超过了应有的时间。我实际上已经看到了数据网格处于会话状态的代码,这使得页面在会话期间保持活动状态。在每个回发后,这种情况一次又一次地发生,直到噗。在这种情况下,GC无法帮助我们,因为对象确实仍在“使用中”。
因此,请尝试简化 - 关闭排序,摆脱第三方控制,使用较小的数据集等。使用内存分析器和使服务器承受压力的事情,测量这种情况。如果你发现没有“泄漏”,那么就开始添加东西以查看它何时变得混乱。
答案 1 :(得分:1)
每次都可能会向iis服务器返回太多数据。请记住,使用带有devexpress网格的标准linq数据源,每次进行排序,分页或任何其他回调的回调时,整个数据都会加载到内存中,然后进行排序和分页。
这意味着如果要加载大量数据,则很容易浪费服务器内存。认为您可能有很多用户打开同一页面,这会将每个用户的整个数据加载到内存中,并且GC可能没有足够的时间来释放所有这些内容。
DevExpress为此提供了LinqServerModeDataSource,它可以完成数据服务器中的所有分页和排序。
如果您不能使用它,请尝试通过过滤来检索较小的数据集。