内存无法释放:.Net应用程序

3

我有一个对象列表,列表中的对象数量约为506,011个。

它在内存中占用了190MB。

一段时间后,我不再需要这个列表。我清空了列表。

list.clear() 命令可以清除该列表中的所有对象。

但是,我的应用程序仍然占用着190MB 的内存。

如何正确地处理该列表?

public class FileProperty
    {
        public string Name { get; set; }
        public string DirectoryPath { get; set; }
        public long LastWriteTime { get; set; }
        public long Size { get; set; }
    }

void Main()
{
   var Sqlite = new SqliteConnection(@"Filename=D:\Work\UserData.db");
   var FileProps=Sqlite.Query<FileProperty>("SELECT *FROM FileProperties;").ToList();

   //Task completed with that collection
   //Now want to free memory
   FileProps.Clear();
   //But memory not freed
}

度量部分非常重要,因为.NET不会将内存返还给操作系统。因此,这取决于观点:从操作系统的角度来看,内存已经消失了(它已经被交给了.NET)。从.NET的角度来看,内存是空的(没有对象)。 - Thomas Weller
我发现 GC.Collect(); Thread.Sleep(1); 的组合非常可靠。Thread.Sleep() 确保操作系统可以切换到 GC 线程。 - Thomas Weller
如果你买不起内存分析器,也可以使用免费但难以学习的调试器[tag:windbg],它可以告诉你有关对象计数的信息。 - Thomas Weller
1
仅添加了一些代码@ThomasWeller - Varun
1
你正在运行调试版本还是发布版本? - Thomas Weller
显示剩余12条评论
2个回答

1

list.Clear()不会重置已分配的列表容量。即使调用Clear()后,容量仍然与之前相同,这意味着底层数组尚未被销毁。

在Clear()之后调用TrimExcess()将重置容量,这可能最终释放内存。

但是,一旦对象没有被任何其他数据结构引用,它应该默认为可垃圾收集。


同样的问题,即使使用TrimExcess()后内存仍未释放。 在任务管理器和VS诊断工具中观察应用程序消耗的内存大小。 - Varun
一个包含20,000个指向对象的指针的数组只有大约400kB,而不是20MB。 - Thomas Weller
@Varun:任务管理器是测量内存的最糟糕的工具之一。你在任务管理器中寻找什么内存?你需要了解“工作集”是什么意思。在90%以上的情况下,工作集不是正确的查看对象。事实上,在我过去的13年中从未如此。 - Thomas Weller
@ThomasWeller 尝试使用数据库中不同的表,列表中有5,06,011个对象引用 大约消耗了195兆字节 - Varun

-1

在清空列表后使用GC.Collect();

编辑:尝试使用FileProps=null;而不是清空。


同样的问题,即使调用 GC.Collect 方法,内存仍未被释放。我正在观察应用程序在任务管理器和 VS 诊断工具中消耗的内存大小。 - Varun
即使 FileProps=null 后,问题仍然存在。 - Varun

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接