我目前正在开发一个需要从REST API服务中搜索元素列表的应用程序。但是每次我搜索时,内存使用情况都会不断增加。
每次我进行搜索时,我都会执行以下步骤: 1.我清理清单 2.我调用一个方法,使我从REST API的请求中获取列表 2.我通过调用请求方法设置列表
myList.clear();
myList = GetListFromREST("https://myrestapi.com/itemList");
async Task<List<Item>> GetListFromREST(string url)
{
List<Item> result;
var response = await new RestService<Response>().GetDataAsyc(url);
if (response.Error.StatusCode == 200)
{
result = response.Data;
}
else
{
throw ex;
}
return result;
}
根据内存诊断工具,内存始终在不断增长。这对我来说没有意义,因为当我做完清除操作后,必须将其还原。
答案 0 :(得分:3)
首先,性能狂潮:https://ericlippert.com/2012/12/17/performance-rant/ 只是为了确保甚至存在需要修复的问题。
关于内存消耗,有两个问题:
您的内存由垃圾收集器管理。 GC的工作需要时间,在所有其他线程必须暂停期间。这也是使生产力倍增器无法工作的宝贵方法,因此这只是您要付出的代价。但是,由于性能的影响,垃圾收集器不希望运行 unessesarily 。确实,如果它仅在应用程序关闭时运行一次,这就是理想情况。
除了显式调用或OutOfMemory异常的 danger 以外,它都不会使其早些运行。如果您确实遇到过OOM,则可以肯定一件事:可以收集的所有内容都已被收集。
如果毕竟这一切仍然需要改进,那么像.NET这样的Managed Runtime可能是错误的起点。您可能甚至会一直进入实时编程。但是考虑到您正在从WEB API检索数据,我要说的是99.99%的可支持性使网络成为瓶颈。
答案 1 :(得分:1)
首先,请确保您有内存消耗问题。如果您将代码片段运行100或1000次该怎么办?消耗的内存水平会稳定还是持续增长?只有无限增长,您才有问题。
如果您的内存消耗稳定在一定水平,则不会出现内存泄漏,因此不应“解决”此问题。
第二,在我看来,打电话
myList.Clear();
没有任何意义。在下一行中,您为引用分配了一个新值,因此,如果系统中没有其他活动对象继续引用您的列表,则旧列表将超出范围,并且GC可以回收内存。
第三,每次调用 GetListFromREST 时,您都会创建一个 RestService 对象的新实例。当该方法返回时,该对象将超出范围并可以回收,但是无论如何都会给GC造成一定压力。当然,GC不会立即收集所有未使用的对象,因此即使对象迅速超出范围,内存消耗也会增加。如果您的 RestService 在后台使用 HttpClient ,则应考虑使其保持活动状态,因为建议重用HttpClient对象而不是不断进行重新创建。