我在内存约束下处理各种列表和类型,并希望在迭代列表时释放内存,因此我设置了一个通用示例:
public class Test
{
List<PersonClass> personList = new(450000);
public Test()
{
for(int i = 0; i < 450000; i++)
{
personList.Add(new PersonClass());
}
}
public List<InfoClass> GetUpdatedList(List<PersonClass> personList)
{
List<InfoClass> secondList = new();
for(int i=personList.Count - 1; i > -1; i--)
{
var aPerson = personList[i];
secondList.Add(new InfoClass()
{
FirstName = aPerson.FirstName,
LastName = aPerson.LastName
});
personList.RemoveAt(i);
}
return secondList;
}
public class PersonClass
{
public string FirstName { get; set; } = "Something Random";
public string LastName { get; set; } = "Something Else Random";
}
public class InfoClass
{
public string FirstName { get; set; } = "Something Random";
public string LastName { get; set; } = "Something Else Random";
public string StateName { get; set; } = "Something Random";
public string CityName { get; set; } = "Something Else Random";
}
}
如何在到达循环结束之前删除元素时释放内存?
如果InfoClass
包含对相应PersonClass
的引用,则可以节省大量内存,而不是创建新字符串。
如果InfoClass
是许多其他对象的摘要,请尝试仅存储对其他对象的引用,而不是复制属性
有几件事:
-
当变量超出范围时,将自动释放变量。如果在大括号内声明变量,那就是它的作用域。
-
当有足够的内存压力来触发垃圾回收器时,垃圾回收器将自动运行。内存压力可能由多种原因引起,但其中之一是无法在堆上为新对象分配足够的连续可用空间。
-
手动运行
GC.Collect()
不受欢迎的原因有很多,其中最重要的是它很慢。你当然不想在任何形式的循环中这样做。 -
如果您不知道应用程序使用了多少内存,并且该内存高于运行时可用的内存量,那么您建议的是过早的优化,这是万恶之源。有一些工具(其中一些内置于Visual Studio中)可以让您确定应用程序在运行时使用了多少内存。一旦你有了这些信息,那么你就可以做出一个明智的决定,你是否应该担心这种优化。
-
如果必须优化,如果您知道
class
可以转换为class
,则可能需要考虑使用struct
而不是 。struct
分配在堆栈而不是堆上,从而节省了一点内存,但它们必须是只读的,并且必须满足特定的大小要求。但是,当它们超出范围时,它们将立即解除分配,堆内存不会成为问题。