我正在学习有关线程的更多信息,并且我使用以下代码创建了一个相当简单的 WPF 应用程序(x64 平台构建)
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
for (var i = 0; i <= 20000; i++)
{
Thread thread = new Thread(Test);
thread.IsBackground = true;
thread.Start();
}
}
public void Test()
{
Thread.Sleep(20000);
}
}
当我运行此代码时,当所有线程都在运行/休眠时,进程大约需要 560MB 的 RAM。
完成后,进程使用量降至约 125 MB RAM。
我的问题是,当应用程序本身(没有线程示例)仅使用 30 MB RAM 时,为什么进程此时使用 125 MB RAM?
它是否使某些线程保持活动状态以供可能的重新/使用或发生其他事情?
EDIT:
由于一些如何改进此代码的建议,我想指出,我并不是在询问改进它的方法,而是要查明此行为的原因。
EDIT 2:
这与线程无关,但我尝试过一个大的案例string
列表在内存中,并且没有产生相同的结果。当list完全加载到内存中时,大约需要1.3GB内存,但是当list设置为NULL
, and GC.Collect()
被调用后,内存使用量如预期回落至 30 MB。
Code:
public partial class MainWindow : Window
{
List<string> stringArray = new List<string>();
public MainWindow()
{
InitializeComponent();
for (var i = 0; i <= 100000000; i++)
{
//Thread thread = new Thread(Test);
//thread.IsBackground = false;
//thread.Start();
stringArray.Add("Some very long string to pump up the memory volume 2 reloaded");
}
stringArray = null;
GC.Collect();
}
}
当线程完成时,每个线程使用的部分内存将被释放。这就是当所有后台线程完成时内存消耗从 560 MB 下降到 125 MB 的原因。
其余内存分配在托管堆上,并将由垃圾收集器释放。
当您的应用程序处于空闲状态时,不会分配新内存,因此不需要运行垃圾收集器。您在评论中提到强制 GC 使用GC.Collect()
没有帮助,但请记住Thread
已实现终结器,因此它将在第一个集合中幸存。你将不得不使用
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
以确保内存被释放。
这应该将内存使用量减少到启动线程之前的水平。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)