When an array is subject to Garbage Collection?









up vote
2
down vote

favorite












A few years ago I read the book the CLR via C# and the other day I got asked whether an array and still got a bit puzzled, the question was to figure out when the array in the method below is available to garbage collection:



public static double ThingRatio()

var input = new 1, 1, 2 ,3, 5 ,8 ;
var count = input.Length;
// Let's suppose that the line below is the last use of the array input
var thingCount = CountThings(input);
input = null;
return (double)thingCount / count;



According to the answer given here: When is an object subject to garbage collection? which states:




They will both become eligible for collection as soon as they are not
needed anymore. This means that under some circumstances, objects can
be collected even before the end of the scope in which they were
defined. On the other hand, the actual collection might also happen
much later.




I would tend to say that starting after line 6 (i.e. input = null;) the array becomes subject to GC but I am not that sure... (I mean the array is supposedly surely no longer needed after the assignment, but also struggling that it's after the CountThings call but at the same time the array is "needed" for the null assignment).










share|improve this question























  • So... you're just having doubts about the accepted answer in that question you linked?
    – Broots Waymb
    Nov 8 at 16:09










  • @Broots Waymb I have a doubt between after the CountThings call and the null assignment
    – Ehouarn Perret
    Nov 8 at 16:10







  • 1




    After the CountThings call the value is still referenced - unless the compiler picks it up and refactors it somehow, I'd say that GC won't touch that value before null assignment.
    – Szab
    Nov 8 at 16:11






  • 4




    i would say its subject to GC before the line of input = null if the compiler is smart enough. If you are wondering about whether you need to assign it to null to help GC then the answer is no. absolutely not necessary
    – Steve
    Nov 8 at 16:11











  • @Steve how can we find this out? I am thinking maybe checking the IL code maybe if the null is not "translated" then that means that this assignment is not needed to make it subject to garbage collection. I am not sure "how dumb" the compiler is.
    – Ehouarn Perret
    Nov 8 at 16:14














up vote
2
down vote

favorite












A few years ago I read the book the CLR via C# and the other day I got asked whether an array and still got a bit puzzled, the question was to figure out when the array in the method below is available to garbage collection:



public static double ThingRatio()

var input = new 1, 1, 2 ,3, 5 ,8 ;
var count = input.Length;
// Let's suppose that the line below is the last use of the array input
var thingCount = CountThings(input);
input = null;
return (double)thingCount / count;



According to the answer given here: When is an object subject to garbage collection? which states:




They will both become eligible for collection as soon as they are not
needed anymore. This means that under some circumstances, objects can
be collected even before the end of the scope in which they were
defined. On the other hand, the actual collection might also happen
much later.




I would tend to say that starting after line 6 (i.e. input = null;) the array becomes subject to GC but I am not that sure... (I mean the array is supposedly surely no longer needed after the assignment, but also struggling that it's after the CountThings call but at the same time the array is "needed" for the null assignment).










share|improve this question























  • So... you're just having doubts about the accepted answer in that question you linked?
    – Broots Waymb
    Nov 8 at 16:09










  • @Broots Waymb I have a doubt between after the CountThings call and the null assignment
    – Ehouarn Perret
    Nov 8 at 16:10







  • 1




    After the CountThings call the value is still referenced - unless the compiler picks it up and refactors it somehow, I'd say that GC won't touch that value before null assignment.
    – Szab
    Nov 8 at 16:11






  • 4




    i would say its subject to GC before the line of input = null if the compiler is smart enough. If you are wondering about whether you need to assign it to null to help GC then the answer is no. absolutely not necessary
    – Steve
    Nov 8 at 16:11











  • @Steve how can we find this out? I am thinking maybe checking the IL code maybe if the null is not "translated" then that means that this assignment is not needed to make it subject to garbage collection. I am not sure "how dumb" the compiler is.
    – Ehouarn Perret
    Nov 8 at 16:14












up vote
2
down vote

favorite









up vote
2
down vote

favorite











A few years ago I read the book the CLR via C# and the other day I got asked whether an array and still got a bit puzzled, the question was to figure out when the array in the method below is available to garbage collection:



public static double ThingRatio()

var input = new 1, 1, 2 ,3, 5 ,8 ;
var count = input.Length;
// Let's suppose that the line below is the last use of the array input
var thingCount = CountThings(input);
input = null;
return (double)thingCount / count;



According to the answer given here: When is an object subject to garbage collection? which states:




They will both become eligible for collection as soon as they are not
needed anymore. This means that under some circumstances, objects can
be collected even before the end of the scope in which they were
defined. On the other hand, the actual collection might also happen
much later.




I would tend to say that starting after line 6 (i.e. input = null;) the array becomes subject to GC but I am not that sure... (I mean the array is supposedly surely no longer needed after the assignment, but also struggling that it's after the CountThings call but at the same time the array is "needed" for the null assignment).










share|improve this question















A few years ago I read the book the CLR via C# and the other day I got asked whether an array and still got a bit puzzled, the question was to figure out when the array in the method below is available to garbage collection:



public static double ThingRatio()

var input = new 1, 1, 2 ,3, 5 ,8 ;
var count = input.Length;
// Let's suppose that the line below is the last use of the array input
var thingCount = CountThings(input);
input = null;
return (double)thingCount / count;



According to the answer given here: When is an object subject to garbage collection? which states:




They will both become eligible for collection as soon as they are not
needed anymore. This means that under some circumstances, objects can
be collected even before the end of the scope in which they were
defined. On the other hand, the actual collection might also happen
much later.




I would tend to say that starting after line 6 (i.e. input = null;) the array becomes subject to GC but I am not that sure... (I mean the array is supposedly surely no longer needed after the assignment, but also struggling that it's after the CountThings call but at the same time the array is "needed" for the null assignment).







c# .net garbage-collection






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 8 at 16:12

























asked Nov 8 at 16:06









Ehouarn Perret

82911130




82911130











  • So... you're just having doubts about the accepted answer in that question you linked?
    – Broots Waymb
    Nov 8 at 16:09










  • @Broots Waymb I have a doubt between after the CountThings call and the null assignment
    – Ehouarn Perret
    Nov 8 at 16:10







  • 1




    After the CountThings call the value is still referenced - unless the compiler picks it up and refactors it somehow, I'd say that GC won't touch that value before null assignment.
    – Szab
    Nov 8 at 16:11






  • 4




    i would say its subject to GC before the line of input = null if the compiler is smart enough. If you are wondering about whether you need to assign it to null to help GC then the answer is no. absolutely not necessary
    – Steve
    Nov 8 at 16:11











  • @Steve how can we find this out? I am thinking maybe checking the IL code maybe if the null is not "translated" then that means that this assignment is not needed to make it subject to garbage collection. I am not sure "how dumb" the compiler is.
    – Ehouarn Perret
    Nov 8 at 16:14
















  • So... you're just having doubts about the accepted answer in that question you linked?
    – Broots Waymb
    Nov 8 at 16:09










  • @Broots Waymb I have a doubt between after the CountThings call and the null assignment
    – Ehouarn Perret
    Nov 8 at 16:10







  • 1




    After the CountThings call the value is still referenced - unless the compiler picks it up and refactors it somehow, I'd say that GC won't touch that value before null assignment.
    – Szab
    Nov 8 at 16:11






  • 4




    i would say its subject to GC before the line of input = null if the compiler is smart enough. If you are wondering about whether you need to assign it to null to help GC then the answer is no. absolutely not necessary
    – Steve
    Nov 8 at 16:11











  • @Steve how can we find this out? I am thinking maybe checking the IL code maybe if the null is not "translated" then that means that this assignment is not needed to make it subject to garbage collection. I am not sure "how dumb" the compiler is.
    – Ehouarn Perret
    Nov 8 at 16:14















So... you're just having doubts about the accepted answer in that question you linked?
– Broots Waymb
Nov 8 at 16:09




So... you're just having doubts about the accepted answer in that question you linked?
– Broots Waymb
Nov 8 at 16:09












@Broots Waymb I have a doubt between after the CountThings call and the null assignment
– Ehouarn Perret
Nov 8 at 16:10





@Broots Waymb I have a doubt between after the CountThings call and the null assignment
– Ehouarn Perret
Nov 8 at 16:10





1




1




After the CountThings call the value is still referenced - unless the compiler picks it up and refactors it somehow, I'd say that GC won't touch that value before null assignment.
– Szab
Nov 8 at 16:11




After the CountThings call the value is still referenced - unless the compiler picks it up and refactors it somehow, I'd say that GC won't touch that value before null assignment.
– Szab
Nov 8 at 16:11




4




4




i would say its subject to GC before the line of input = null if the compiler is smart enough. If you are wondering about whether you need to assign it to null to help GC then the answer is no. absolutely not necessary
– Steve
Nov 8 at 16:11





i would say its subject to GC before the line of input = null if the compiler is smart enough. If you are wondering about whether you need to assign it to null to help GC then the answer is no. absolutely not necessary
– Steve
Nov 8 at 16:11













@Steve how can we find this out? I am thinking maybe checking the IL code maybe if the null is not "translated" then that means that this assignment is not needed to make it subject to garbage collection. I am not sure "how dumb" the compiler is.
– Ehouarn Perret
Nov 8 at 16:14




@Steve how can we find this out? I am thinking maybe checking the IL code maybe if the null is not "translated" then that means that this assignment is not needed to make it subject to garbage collection. I am not sure "how dumb" the compiler is.
– Ehouarn Perret
Nov 8 at 16:14












3 Answers
3






active

oldest

votes

















up vote
6
down vote



accepted










Remember objects and variables are not the same thing. A variable has a scope to particular method or type, but the object it refers to or used to refer to has no such concept; it's just a blob of memory. If the GC runs after input = null; but before the end of the method, the array is just one more orphaned object. It's not reachable, and therefore eligible for collection.



And "reachable" (rather then "needed" ) is the key word here. The array object is no longer needed after this line: var thingCount = CountThings(input);. However, it's still reachable, and so could not be collected at that point...



We also need to remember it isn't collected right away. It's only eligible to be collected. As a practical matter, I've found the .Net runtime doesn't tend to invoke the GC in the middle of a user method unless it really has to. Generally speaking, it is not needed or helpful to set a variable to null early, and in some rare cases can even be harmful.



Finally, I'll add that the code we read and write is not the same code actually used by the machine. Remember, there is also a compile step to translate all this to IL, and later a JIT process to create the final machine code that really runs. Even concept of one line following next is already an abstraction away from what actually happens. One line may expand to be several lines of actual IL, or in some cases even be re-written to involve all new compiler-generated types as with closures or iterator blocks. So everything here is really only referring to the simple case.






share|improve this answer






















  • true I think even at the IL stage (I played with sharplab.io) the null assignment already disappeared
    – Ehouarn Perret
    Nov 8 at 16:28


















up vote
4
down vote














GC Myth: setting an object's reference to null will force the GC to collect it right away.

GC Truth: setting an object's reference to null will sometimes allow the GC to collect it sooner.




Taking part of the blogpost I'm referencing below and applying it to your question, the answer is as follows:



The JIT is usually smart enough to realize that input = null can be optimized away. That leaves CountThings(input) as the last reference to the object. So after that call, the input is no longer used and is removed as a GC Root. That leaves the Object in memory orphaned (no references pointing to it), making it eligible for collection. When the GC actually goes about collecting it, is another matter.



More information to be found at To Null or Not to Null






share|improve this answer



























    up vote
    1
    down vote













    No object can be garbage-collected while it is recognized as existing. An object will exist in .NET for as along as any reference to it exists or it has a registered finalizer, and will cease to exist once neither condition applies. References in objects will exist as long as the objects themselves exist, and references in automatic variables will exist as long as there is any means via which they will be observed. If the garbage collector detects that the only references to an object with no registered finalizer are held in weak references, those references will be destroyed, causing the object to cease to exist. If the garbage collector detects that the only references to an object with a registered finalizer are held in weak references, any weak references whose "track resurrection" property is false, a reference to the object will be placed in a strongly-rooted list of objects needing "immediate" finalization, and the finalizer will be unregistered (thus allowing it to cease to exist if and when the finalizer reaches a point in execution where no reference to the object could ever be observed).



    Note that some sources confuse the triggering of an object's finalizer with garbage-collection, but an object whose finalizer is triggered is guaranteed to continue to exist for at least as long as that finalizer takes to execute, and may continue to exist indefinitely if any references to it exist when the finalizer finishes execution.



    In your example, there are three scenarios that could apply, depending upon what CountThings does with the passed-in reference:



    1. If CountThings does not store a copy of the reference anywhere, or any copies of references that it does store get overwritten before input gets overwritten, then it will cease to exist as soon as input gets overwritten or ceases to exist [automatic-duration variables may cease to exist any time a compiler determines that their value will no longer be observed].


    2. If CountThings stores a copy of the reference somewhere that continues to exist after it returns, and the last extant reference is held by something other than a weak reference, then the object will cease to exist as soon as the last reference is destroyed.


    3. If the last existing reference the array ends up being held in a weak reference, the array will continue to exist until the first GC cycle where that is the case, whereupon the weak reference will be cleared, causing the array to cease to exist. Note that the lack of non-weak references to the array will only be relevant when a GC cycle occurs. It is possible (and not particularly uncommon) for a program to store a copy of a reference into a WeakReference, ConditionalWeakTable, or other object holding some form of weak reference, destroy all other copies, and then read out the weak reference to produce a non-weak copy of the reference before the next GC cycle. If that occurs, the system will neither know nor care that there was a time when non non-weak copies of the reference existed. If the GC cycle occurs before the reference gets read out, however, then code which later examines the weak reference will find it blank.


    A key observation is that while finalizers and weak references complicate things slightly, the only way in which the GC destroys objects is by invalidating weak forms of references. As far as the GC is concerned, the only kinds of storage that exist when the system isn't actually performing a GC cycle are those used by objects that exist, those used for .NET's internal purposes, and regions of storage that are available to satisfy future allocations. If an object is created, the storage it occupied will cease to be a region of storage available for future allocations. If the object later ceases to exist, the storage that had contained the object will also cease to exist in any form the GC knows about until the next GC cycle. The next GC cycle won't destroy the object (which had already ceased to exist), but will instead add the storage which had contained it back to its list of areas that are available to add future allocations (causing that storage to exist again).






    share|improve this answer




















      Your Answer






      StackExchange.ifUsing("editor", function ()
      StackExchange.using("externalEditor", function ()
      StackExchange.using("snippets", function ()
      StackExchange.snippets.init();
      );
      );
      , "code-snippets");

      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "1"
      ;
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function()
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled)
      StackExchange.using("snippets", function()
      createEditor();
      );

      else
      createEditor();

      );

      function createEditor()
      StackExchange.prepareEditor(
      heartbeatType: 'answer',
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader:
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      ,
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      );



      );













       

      draft saved


      draft discarded


















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53211655%2fwhen-an-array-is-subject-to-garbage-collection%23new-answer', 'question_page');

      );

      Post as a guest















      Required, but never shown

























      3 Answers
      3






      active

      oldest

      votes








      3 Answers
      3






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      6
      down vote



      accepted










      Remember objects and variables are not the same thing. A variable has a scope to particular method or type, but the object it refers to or used to refer to has no such concept; it's just a blob of memory. If the GC runs after input = null; but before the end of the method, the array is just one more orphaned object. It's not reachable, and therefore eligible for collection.



      And "reachable" (rather then "needed" ) is the key word here. The array object is no longer needed after this line: var thingCount = CountThings(input);. However, it's still reachable, and so could not be collected at that point...



      We also need to remember it isn't collected right away. It's only eligible to be collected. As a practical matter, I've found the .Net runtime doesn't tend to invoke the GC in the middle of a user method unless it really has to. Generally speaking, it is not needed or helpful to set a variable to null early, and in some rare cases can even be harmful.



      Finally, I'll add that the code we read and write is not the same code actually used by the machine. Remember, there is also a compile step to translate all this to IL, and later a JIT process to create the final machine code that really runs. Even concept of one line following next is already an abstraction away from what actually happens. One line may expand to be several lines of actual IL, or in some cases even be re-written to involve all new compiler-generated types as with closures or iterator blocks. So everything here is really only referring to the simple case.






      share|improve this answer






















      • true I think even at the IL stage (I played with sharplab.io) the null assignment already disappeared
        – Ehouarn Perret
        Nov 8 at 16:28















      up vote
      6
      down vote



      accepted










      Remember objects and variables are not the same thing. A variable has a scope to particular method or type, but the object it refers to or used to refer to has no such concept; it's just a blob of memory. If the GC runs after input = null; but before the end of the method, the array is just one more orphaned object. It's not reachable, and therefore eligible for collection.



      And "reachable" (rather then "needed" ) is the key word here. The array object is no longer needed after this line: var thingCount = CountThings(input);. However, it's still reachable, and so could not be collected at that point...



      We also need to remember it isn't collected right away. It's only eligible to be collected. As a practical matter, I've found the .Net runtime doesn't tend to invoke the GC in the middle of a user method unless it really has to. Generally speaking, it is not needed or helpful to set a variable to null early, and in some rare cases can even be harmful.



      Finally, I'll add that the code we read and write is not the same code actually used by the machine. Remember, there is also a compile step to translate all this to IL, and later a JIT process to create the final machine code that really runs. Even concept of one line following next is already an abstraction away from what actually happens. One line may expand to be several lines of actual IL, or in some cases even be re-written to involve all new compiler-generated types as with closures or iterator blocks. So everything here is really only referring to the simple case.






      share|improve this answer






















      • true I think even at the IL stage (I played with sharplab.io) the null assignment already disappeared
        – Ehouarn Perret
        Nov 8 at 16:28













      up vote
      6
      down vote



      accepted







      up vote
      6
      down vote



      accepted






      Remember objects and variables are not the same thing. A variable has a scope to particular method or type, but the object it refers to or used to refer to has no such concept; it's just a blob of memory. If the GC runs after input = null; but before the end of the method, the array is just one more orphaned object. It's not reachable, and therefore eligible for collection.



      And "reachable" (rather then "needed" ) is the key word here. The array object is no longer needed after this line: var thingCount = CountThings(input);. However, it's still reachable, and so could not be collected at that point...



      We also need to remember it isn't collected right away. It's only eligible to be collected. As a practical matter, I've found the .Net runtime doesn't tend to invoke the GC in the middle of a user method unless it really has to. Generally speaking, it is not needed or helpful to set a variable to null early, and in some rare cases can even be harmful.



      Finally, I'll add that the code we read and write is not the same code actually used by the machine. Remember, there is also a compile step to translate all this to IL, and later a JIT process to create the final machine code that really runs. Even concept of one line following next is already an abstraction away from what actually happens. One line may expand to be several lines of actual IL, or in some cases even be re-written to involve all new compiler-generated types as with closures or iterator blocks. So everything here is really only referring to the simple case.






      share|improve this answer














      Remember objects and variables are not the same thing. A variable has a scope to particular method or type, but the object it refers to or used to refer to has no such concept; it's just a blob of memory. If the GC runs after input = null; but before the end of the method, the array is just one more orphaned object. It's not reachable, and therefore eligible for collection.



      And "reachable" (rather then "needed" ) is the key word here. The array object is no longer needed after this line: var thingCount = CountThings(input);. However, it's still reachable, and so could not be collected at that point...



      We also need to remember it isn't collected right away. It's only eligible to be collected. As a practical matter, I've found the .Net runtime doesn't tend to invoke the GC in the middle of a user method unless it really has to. Generally speaking, it is not needed or helpful to set a variable to null early, and in some rare cases can even be harmful.



      Finally, I'll add that the code we read and write is not the same code actually used by the machine. Remember, there is also a compile step to translate all this to IL, and later a JIT process to create the final machine code that really runs. Even concept of one line following next is already an abstraction away from what actually happens. One line may expand to be several lines of actual IL, or in some cases even be re-written to involve all new compiler-generated types as with closures or iterator blocks. So everything here is really only referring to the simple case.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Nov 8 at 20:09

























      answered Nov 8 at 16:17









      Joel Coehoorn

      303k94489717




      303k94489717











      • true I think even at the IL stage (I played with sharplab.io) the null assignment already disappeared
        – Ehouarn Perret
        Nov 8 at 16:28

















      • true I think even at the IL stage (I played with sharplab.io) the null assignment already disappeared
        – Ehouarn Perret
        Nov 8 at 16:28
















      true I think even at the IL stage (I played with sharplab.io) the null assignment already disappeared
      – Ehouarn Perret
      Nov 8 at 16:28





      true I think even at the IL stage (I played with sharplab.io) the null assignment already disappeared
      – Ehouarn Perret
      Nov 8 at 16:28













      up vote
      4
      down vote














      GC Myth: setting an object's reference to null will force the GC to collect it right away.

      GC Truth: setting an object's reference to null will sometimes allow the GC to collect it sooner.




      Taking part of the blogpost I'm referencing below and applying it to your question, the answer is as follows:



      The JIT is usually smart enough to realize that input = null can be optimized away. That leaves CountThings(input) as the last reference to the object. So after that call, the input is no longer used and is removed as a GC Root. That leaves the Object in memory orphaned (no references pointing to it), making it eligible for collection. When the GC actually goes about collecting it, is another matter.



      More information to be found at To Null or Not to Null






      share|improve this answer
























        up vote
        4
        down vote














        GC Myth: setting an object's reference to null will force the GC to collect it right away.

        GC Truth: setting an object's reference to null will sometimes allow the GC to collect it sooner.




        Taking part of the blogpost I'm referencing below and applying it to your question, the answer is as follows:



        The JIT is usually smart enough to realize that input = null can be optimized away. That leaves CountThings(input) as the last reference to the object. So after that call, the input is no longer used and is removed as a GC Root. That leaves the Object in memory orphaned (no references pointing to it), making it eligible for collection. When the GC actually goes about collecting it, is another matter.



        More information to be found at To Null or Not to Null






        share|improve this answer






















          up vote
          4
          down vote










          up vote
          4
          down vote










          GC Myth: setting an object's reference to null will force the GC to collect it right away.

          GC Truth: setting an object's reference to null will sometimes allow the GC to collect it sooner.




          Taking part of the blogpost I'm referencing below and applying it to your question, the answer is as follows:



          The JIT is usually smart enough to realize that input = null can be optimized away. That leaves CountThings(input) as the last reference to the object. So after that call, the input is no longer used and is removed as a GC Root. That leaves the Object in memory orphaned (no references pointing to it), making it eligible for collection. When the GC actually goes about collecting it, is another matter.



          More information to be found at To Null or Not to Null






          share|improve this answer













          GC Myth: setting an object's reference to null will force the GC to collect it right away.

          GC Truth: setting an object's reference to null will sometimes allow the GC to collect it sooner.




          Taking part of the blogpost I'm referencing below and applying it to your question, the answer is as follows:



          The JIT is usually smart enough to realize that input = null can be optimized away. That leaves CountThings(input) as the last reference to the object. So after that call, the input is no longer used and is removed as a GC Root. That leaves the Object in memory orphaned (no references pointing to it), making it eligible for collection. When the GC actually goes about collecting it, is another matter.



          More information to be found at To Null or Not to Null







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 8 at 16:18









          rickvdbosch

          2,81121119




          2,81121119




















              up vote
              1
              down vote













              No object can be garbage-collected while it is recognized as existing. An object will exist in .NET for as along as any reference to it exists or it has a registered finalizer, and will cease to exist once neither condition applies. References in objects will exist as long as the objects themselves exist, and references in automatic variables will exist as long as there is any means via which they will be observed. If the garbage collector detects that the only references to an object with no registered finalizer are held in weak references, those references will be destroyed, causing the object to cease to exist. If the garbage collector detects that the only references to an object with a registered finalizer are held in weak references, any weak references whose "track resurrection" property is false, a reference to the object will be placed in a strongly-rooted list of objects needing "immediate" finalization, and the finalizer will be unregistered (thus allowing it to cease to exist if and when the finalizer reaches a point in execution where no reference to the object could ever be observed).



              Note that some sources confuse the triggering of an object's finalizer with garbage-collection, but an object whose finalizer is triggered is guaranteed to continue to exist for at least as long as that finalizer takes to execute, and may continue to exist indefinitely if any references to it exist when the finalizer finishes execution.



              In your example, there are three scenarios that could apply, depending upon what CountThings does with the passed-in reference:



              1. If CountThings does not store a copy of the reference anywhere, or any copies of references that it does store get overwritten before input gets overwritten, then it will cease to exist as soon as input gets overwritten or ceases to exist [automatic-duration variables may cease to exist any time a compiler determines that their value will no longer be observed].


              2. If CountThings stores a copy of the reference somewhere that continues to exist after it returns, and the last extant reference is held by something other than a weak reference, then the object will cease to exist as soon as the last reference is destroyed.


              3. If the last existing reference the array ends up being held in a weak reference, the array will continue to exist until the first GC cycle where that is the case, whereupon the weak reference will be cleared, causing the array to cease to exist. Note that the lack of non-weak references to the array will only be relevant when a GC cycle occurs. It is possible (and not particularly uncommon) for a program to store a copy of a reference into a WeakReference, ConditionalWeakTable, or other object holding some form of weak reference, destroy all other copies, and then read out the weak reference to produce a non-weak copy of the reference before the next GC cycle. If that occurs, the system will neither know nor care that there was a time when non non-weak copies of the reference existed. If the GC cycle occurs before the reference gets read out, however, then code which later examines the weak reference will find it blank.


              A key observation is that while finalizers and weak references complicate things slightly, the only way in which the GC destroys objects is by invalidating weak forms of references. As far as the GC is concerned, the only kinds of storage that exist when the system isn't actually performing a GC cycle are those used by objects that exist, those used for .NET's internal purposes, and regions of storage that are available to satisfy future allocations. If an object is created, the storage it occupied will cease to be a region of storage available for future allocations. If the object later ceases to exist, the storage that had contained the object will also cease to exist in any form the GC knows about until the next GC cycle. The next GC cycle won't destroy the object (which had already ceased to exist), but will instead add the storage which had contained it back to its list of areas that are available to add future allocations (causing that storage to exist again).






              share|improve this answer
























                up vote
                1
                down vote













                No object can be garbage-collected while it is recognized as existing. An object will exist in .NET for as along as any reference to it exists or it has a registered finalizer, and will cease to exist once neither condition applies. References in objects will exist as long as the objects themselves exist, and references in automatic variables will exist as long as there is any means via which they will be observed. If the garbage collector detects that the only references to an object with no registered finalizer are held in weak references, those references will be destroyed, causing the object to cease to exist. If the garbage collector detects that the only references to an object with a registered finalizer are held in weak references, any weak references whose "track resurrection" property is false, a reference to the object will be placed in a strongly-rooted list of objects needing "immediate" finalization, and the finalizer will be unregistered (thus allowing it to cease to exist if and when the finalizer reaches a point in execution where no reference to the object could ever be observed).



                Note that some sources confuse the triggering of an object's finalizer with garbage-collection, but an object whose finalizer is triggered is guaranteed to continue to exist for at least as long as that finalizer takes to execute, and may continue to exist indefinitely if any references to it exist when the finalizer finishes execution.



                In your example, there are three scenarios that could apply, depending upon what CountThings does with the passed-in reference:



                1. If CountThings does not store a copy of the reference anywhere, or any copies of references that it does store get overwritten before input gets overwritten, then it will cease to exist as soon as input gets overwritten or ceases to exist [automatic-duration variables may cease to exist any time a compiler determines that their value will no longer be observed].


                2. If CountThings stores a copy of the reference somewhere that continues to exist after it returns, and the last extant reference is held by something other than a weak reference, then the object will cease to exist as soon as the last reference is destroyed.


                3. If the last existing reference the array ends up being held in a weak reference, the array will continue to exist until the first GC cycle where that is the case, whereupon the weak reference will be cleared, causing the array to cease to exist. Note that the lack of non-weak references to the array will only be relevant when a GC cycle occurs. It is possible (and not particularly uncommon) for a program to store a copy of a reference into a WeakReference, ConditionalWeakTable, or other object holding some form of weak reference, destroy all other copies, and then read out the weak reference to produce a non-weak copy of the reference before the next GC cycle. If that occurs, the system will neither know nor care that there was a time when non non-weak copies of the reference existed. If the GC cycle occurs before the reference gets read out, however, then code which later examines the weak reference will find it blank.


                A key observation is that while finalizers and weak references complicate things slightly, the only way in which the GC destroys objects is by invalidating weak forms of references. As far as the GC is concerned, the only kinds of storage that exist when the system isn't actually performing a GC cycle are those used by objects that exist, those used for .NET's internal purposes, and regions of storage that are available to satisfy future allocations. If an object is created, the storage it occupied will cease to be a region of storage available for future allocations. If the object later ceases to exist, the storage that had contained the object will also cease to exist in any form the GC knows about until the next GC cycle. The next GC cycle won't destroy the object (which had already ceased to exist), but will instead add the storage which had contained it back to its list of areas that are available to add future allocations (causing that storage to exist again).






                share|improve this answer






















                  up vote
                  1
                  down vote










                  up vote
                  1
                  down vote









                  No object can be garbage-collected while it is recognized as existing. An object will exist in .NET for as along as any reference to it exists or it has a registered finalizer, and will cease to exist once neither condition applies. References in objects will exist as long as the objects themselves exist, and references in automatic variables will exist as long as there is any means via which they will be observed. If the garbage collector detects that the only references to an object with no registered finalizer are held in weak references, those references will be destroyed, causing the object to cease to exist. If the garbage collector detects that the only references to an object with a registered finalizer are held in weak references, any weak references whose "track resurrection" property is false, a reference to the object will be placed in a strongly-rooted list of objects needing "immediate" finalization, and the finalizer will be unregistered (thus allowing it to cease to exist if and when the finalizer reaches a point in execution where no reference to the object could ever be observed).



                  Note that some sources confuse the triggering of an object's finalizer with garbage-collection, but an object whose finalizer is triggered is guaranteed to continue to exist for at least as long as that finalizer takes to execute, and may continue to exist indefinitely if any references to it exist when the finalizer finishes execution.



                  In your example, there are three scenarios that could apply, depending upon what CountThings does with the passed-in reference:



                  1. If CountThings does not store a copy of the reference anywhere, or any copies of references that it does store get overwritten before input gets overwritten, then it will cease to exist as soon as input gets overwritten or ceases to exist [automatic-duration variables may cease to exist any time a compiler determines that their value will no longer be observed].


                  2. If CountThings stores a copy of the reference somewhere that continues to exist after it returns, and the last extant reference is held by something other than a weak reference, then the object will cease to exist as soon as the last reference is destroyed.


                  3. If the last existing reference the array ends up being held in a weak reference, the array will continue to exist until the first GC cycle where that is the case, whereupon the weak reference will be cleared, causing the array to cease to exist. Note that the lack of non-weak references to the array will only be relevant when a GC cycle occurs. It is possible (and not particularly uncommon) for a program to store a copy of a reference into a WeakReference, ConditionalWeakTable, or other object holding some form of weak reference, destroy all other copies, and then read out the weak reference to produce a non-weak copy of the reference before the next GC cycle. If that occurs, the system will neither know nor care that there was a time when non non-weak copies of the reference existed. If the GC cycle occurs before the reference gets read out, however, then code which later examines the weak reference will find it blank.


                  A key observation is that while finalizers and weak references complicate things slightly, the only way in which the GC destroys objects is by invalidating weak forms of references. As far as the GC is concerned, the only kinds of storage that exist when the system isn't actually performing a GC cycle are those used by objects that exist, those used for .NET's internal purposes, and regions of storage that are available to satisfy future allocations. If an object is created, the storage it occupied will cease to be a region of storage available for future allocations. If the object later ceases to exist, the storage that had contained the object will also cease to exist in any form the GC knows about until the next GC cycle. The next GC cycle won't destroy the object (which had already ceased to exist), but will instead add the storage which had contained it back to its list of areas that are available to add future allocations (causing that storage to exist again).






                  share|improve this answer












                  No object can be garbage-collected while it is recognized as existing. An object will exist in .NET for as along as any reference to it exists or it has a registered finalizer, and will cease to exist once neither condition applies. References in objects will exist as long as the objects themselves exist, and references in automatic variables will exist as long as there is any means via which they will be observed. If the garbage collector detects that the only references to an object with no registered finalizer are held in weak references, those references will be destroyed, causing the object to cease to exist. If the garbage collector detects that the only references to an object with a registered finalizer are held in weak references, any weak references whose "track resurrection" property is false, a reference to the object will be placed in a strongly-rooted list of objects needing "immediate" finalization, and the finalizer will be unregistered (thus allowing it to cease to exist if and when the finalizer reaches a point in execution where no reference to the object could ever be observed).



                  Note that some sources confuse the triggering of an object's finalizer with garbage-collection, but an object whose finalizer is triggered is guaranteed to continue to exist for at least as long as that finalizer takes to execute, and may continue to exist indefinitely if any references to it exist when the finalizer finishes execution.



                  In your example, there are three scenarios that could apply, depending upon what CountThings does with the passed-in reference:



                  1. If CountThings does not store a copy of the reference anywhere, or any copies of references that it does store get overwritten before input gets overwritten, then it will cease to exist as soon as input gets overwritten or ceases to exist [automatic-duration variables may cease to exist any time a compiler determines that their value will no longer be observed].


                  2. If CountThings stores a copy of the reference somewhere that continues to exist after it returns, and the last extant reference is held by something other than a weak reference, then the object will cease to exist as soon as the last reference is destroyed.


                  3. If the last existing reference the array ends up being held in a weak reference, the array will continue to exist until the first GC cycle where that is the case, whereupon the weak reference will be cleared, causing the array to cease to exist. Note that the lack of non-weak references to the array will only be relevant when a GC cycle occurs. It is possible (and not particularly uncommon) for a program to store a copy of a reference into a WeakReference, ConditionalWeakTable, or other object holding some form of weak reference, destroy all other copies, and then read out the weak reference to produce a non-weak copy of the reference before the next GC cycle. If that occurs, the system will neither know nor care that there was a time when non non-weak copies of the reference existed. If the GC cycle occurs before the reference gets read out, however, then code which later examines the weak reference will find it blank.


                  A key observation is that while finalizers and weak references complicate things slightly, the only way in which the GC destroys objects is by invalidating weak forms of references. As far as the GC is concerned, the only kinds of storage that exist when the system isn't actually performing a GC cycle are those used by objects that exist, those used for .NET's internal purposes, and regions of storage that are available to satisfy future allocations. If an object is created, the storage it occupied will cease to be a region of storage available for future allocations. If the object later ceases to exist, the storage that had contained the object will also cease to exist in any form the GC knows about until the next GC cycle. The next GC cycle won't destroy the object (which had already ceased to exist), but will instead add the storage which had contained it back to its list of areas that are available to add future allocations (causing that storage to exist again).







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 8 at 17:09









                  supercat

                  55.5k2114146




                  55.5k2114146



























                       

                      draft saved


                      draft discarded















































                       


                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53211655%2fwhen-an-array-is-subject-to-garbage-collection%23new-answer', 'question_page');

                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

                      Edmonton

                      Crossroads (UK TV series)