-2

If there is an object with infinite loop, will it ever be garbage collected (while thread is running)?

I made a program to test this and it seems it will never be garbage collected, but I'd like someone with more experience to confirm this.

EDIT: I forgot to add example. Here is example which I have used.

class Program
{
    static void Main(string[] args)
    {
        WeakReference wr1 = InitializeClassWithLoop();
        WeakReference wr2 = InitializeClassWithoutLoop();

        GC.Collect(2);
        GC.Collect(2);
        GC.Collect(2);
        GC.WaitForPendingFinalizers();

        Thread.Sleep(30000);
        Console.WriteLine($"ClassWithLoop.IsAlive = {wr1.IsAlive}\nClassWithoutLoop.IsAlive = {wr2.IsAlive}\n");
        Console.ReadLine();
    }

    static WeakReference InitializeClassWithLoop()
    {
        var cs = new ClassWithLoop();
        return new WeakReference(cs);
    }

    static WeakReference InitializeClassWithoutLoop()
    {
        var cs = new ClassWithoutLoop();
        return new WeakReference(cs);
    }
}

public class ClassWithLoop
{
    public ClassWithLoop()
    {
        Thread thread = new Thread(Loop);
        thread.Start();
    }

    private void Loop()
    {
        int counter = 0;
        while (true)
        {
            counter++;
            Thread.Sleep(1000);
        }
    }
}

public class ClassWithoutLoop
{
    int counter;

    public ClassWithoutLoop()
    {
        counter = 5;
    }
}

Result is:
ClassWithLoop.IsAlive = True
ClassWithoutLoop.IsAlive = False

vlada
  • 155
  • 1
  • 2
  • 12
  • Object used in infinite loop you mean? – EpicKip Aug 09 '17 at 11:58
  • are you using same object or creating new one on every loop? – Power Star Aug 09 '17 at 11:58
  • 2
    what does "object with a loop" mean? an object will never be garbage collected as long as your process (no matter which thread) has a reference to that object. – René Vogt Aug 09 '17 at 11:58
  • Please provide some code to demonstrate what you are asking about. – René Vogt Aug 09 '17 at 11:59
  • @RenéVogt Correct me if I am wrong.. If we create new object on loop then the older objects will be collected right?? – Power Star Aug 09 '17 at 11:59
  • Only objects that are no longer referenced (e.g. no variable "points" to them) _can_ be garbage collected. Objects that are still referenced will not be collected. If you create new ones or not does not matter. _When_ exactly the (no longer referenced) objects get collected depends on other things like gc strategy and memory pressure. – René Vogt Aug 09 '17 at 12:01
  • @PowerStar, only if you remove all references to them and the garbage collector determines it needs to run. – David Arno Aug 09 '17 at 12:02
  • @DavidArno removing all reference means not using the object right? – Power Star Aug 09 '17 at 12:03
  • I repeat: if you would provide an [mcve] we may be able to give an exact answer. – René Vogt Aug 09 '17 at 12:05
  • 1
    @PowerStar, if for example, you have the line `var x = new SomeType();` in that loop and you do not assign `x` to anything else in the loop, then all those previous `SomeType`'s aren't referenced and so are eligible for garbage collection. – David Arno Aug 09 '17 at 12:08
  • `Only objects that are no longer referenced (e.g. no variable "points" to them) can be garbage collected. ` Your main point is correct, although your bit in brackets less so. https://blogs.msdn.microsoft.com/cbrumme/2003/04/19/lifetime-gc-keepalive-handle-recycling/ may be of interest. – mjwills Aug 09 '17 at 12:27
  • @RenéVogt it means object which starts thread with infinite loop. – vlada Aug 09 '17 at 12:49
  • I added an example. – vlada Aug 09 '17 at 12:49

1 Answers1

1

I can only assume you mean a class has a method with an infinite loop inside it:

public class A
{
  public void IDontEverEnd()
  {
    while(true) { }
  }
}

Assuming you then do something like this:

Task.Factory.StartNew(() => {
  new A().IDontEverEnd();
})

Then your program will remain active, as this will just run on a separate thread, but NO it will not be garbage collected; this is because the call to IDontEverEnd never exits, and therefore the reference to the instance of A never falls out of use.


EDIT

As mjwills mentions in the comments, it is possible sometimes for an item to be garbage collected, even if a method is being executed on it.

Though in practice, so long as you're not dealing with p/invoke stuff, chances are this won't matter to you.

Community
  • 1
  • 1
Clint
  • 6,133
  • 2
  • 27
  • 48
  • As https://blogs.msdn.microsoft.com/cbrumme/2003/04/19/lifetime-gc-keepalive-handle-recycling/ states `In other words, ‘this’ can be collected even while you are executing an instance method on that object.` It is rare that makes a meaningful difference, but something to be aware of. – mjwills Aug 09 '17 at 12:15
  • @mjwills oh, that's interesting! – Clint Aug 09 '17 at 12:18