在循环结束之前循环访问列表时释放内存



我在内存约束下处理各种列表和类型,并希望在迭代列表时释放内存,因此我设置了一个通用示例:

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是许多其他对象的摘要,请尝试仅存储对其他对象的引用,而不是复制属性

有几件事:

  1. 当变量超出范围时,将自动释放变量。如果在大括号内声明变量,那就是它的作用域。

  2. 当有足够的内存压力来触发垃圾回收器时,垃圾回收器将自动运行。内存压力可能由多种原因引起,但其中之一是无法在堆上为新对象分配足够的连续可用空间。

  3. 手动运行GC.Collect()不受欢迎的原因有很多,其中最重要的是它很慢。你当然不想在任何形式的循环中这样做。

  4. 如果您不知道应用程序使用了多少内存,并且该内存高于运行时可用的内存量,那么您建议的是过早的优化,这是万恶之源。有一些工具(其中一些内置于Visual Studio中)可以让您确定应用程序在运行时使用了多少内存。一旦你有了这些信息,那么你就可以做出一个明智的决定,你是否应该担心这种优化。

  5. 如果必须优化,如果您知道class可以转换为class,则可能需要考虑使用struct而不是 。struct分配在堆栈而不是堆上,从而节省了一点内存,但它们必须是只读的,并且必须满足特定的大小要求。但是,当它们超出范围时,它们将立即解除分配,堆内存不会成为问题。

最新更新