Why Garbage Collector doesn't collect Tasks objects

生来就可爱ヽ(ⅴ<●) 提交于 2020-01-23 13:24:08

问题


especially when no live Thread reference it.

I thought GC goes thought all .net threads to find references... Does it check references in other places too?

EDIT: FOr instance let's imagine we are in a console app, the main calls a method that creates a local task1, then applies a task1.ContinueWith(task2) and returns to main, main do console.readline().

At this point it could be that task1 has finished, task2 still has not started a GC could start and no thread has a reference to task2. Why task2 doesn't get GC'ed?

EDIT2: Probably I'm not using the right words when saying "task"

using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication
{
    class Program
    {
        static void Launch()
        {
            var task1 = Task.Run(() => Thread.Sleep(60000))
            task1.ContinueWith(() =>  WriteToFile("Hi"));
        }

        static void Main(string[] args)
        {
            Launch();
            //At this point if a GC occurs which thread or static file has a reference to "()=>WriteTofile("Hi")" ?
            Console.ReadLine();
        }

There is the main thread waiting for the console, one thread (maybe from the threadpool) running the Sleep. Just after the Sleep is done, and before the WriteToFile thread start, a GC could happen, isn't it?


回答1:


The reference to task1 is being held by the default task scheduler, (The default task scheduler is static).

The continuation is kept alive by task1 until it is handed off to it's assigned the task scheduler (TaskScheduler.Current at the time of creation by default).

(Note, these are likely not the only possible roots, just the ones I quickly found looking through the source)




回答2:


I suspect that part of your misunderstanding is that there is no reason that the code you've written would run a garbage collection. You say "just after the Sleep ... a GC could happen[?]" but actually, no: the garbage collector will not run simply because nothing is happening.

Automatic garbage collection in .NET happens when you allocate memory. That is: when you evaluate an expression and that value is written to memory. Garbage collection applies only to the heap, so typically a GC is triggered when you create an instance of a class by calling a constructor.

Even then, garbage collection will only happen if there is not enough free memory in generation 0 to store the newly-created object (and even then, assuming the object isn't so large that it goes straight into the Large Object Heap).

With that in mind, the code you've posted doesn't allocate enough memory to ever trigger a GC, and so I'd not expect any of the objects created there to be collected until the program terminates.



来源:https://stackoverflow.com/questions/38531077/why-garbage-collector-doesnt-collect-tasks-objects

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!