0

I have ClassA, ClassB and a Thread B. ClassA will ask ClassB to collect data from database server. After doing so, ClassA will copy data from ClassB using List.add. I understand that ClassA elements are shallow copies of ClassB (only copy references).

After copying, ClassB will be out of scope and GC may dispose of it.

  1. Will GC dispose of ClassB even objects created in ClassB are still referenced by ClassA?

  2. Or keeps ClassB in memory?

  3. Or keeps only objects that are referenced by other class and dispose of none used objects.

Neuron
  • 5,141
  • 5
  • 38
  • 59
alsaleem
  • 347
  • 3
  • 16
  • It is 3. Though the object are (highly) unlikely to be garbage collected immediately. – Stephen C Jun 24 '18 at 22:48
  • ClassB will be instantiated many/many times, GC wil sure remove it as memory will get larger soon. ClassB has many other unrelated data to ClassA. – alsaleem Jun 24 '18 at 23:03
  • So long as there are no strong references to ClassB it will be eligible for GC. However, since you mention that ClassB is a `Thread` note that it is also a "root". ClassB will also have to terminate (in the context of a thread) in order to be eligible for GC. More at https://stackoverflow.com/questions/2423284/java-thread-garbage-collected-or-not – Slaw Jun 24 '18 at 23:10
  • The original List<> of ClassB will be GC. Will elements be lost too? – alsaleem Jun 24 '18 at 23:11
  • The `List` may be GC but as you mentioned all the elements are in another, new `List` inside ClassA. Therefore the elements of the original `List` will remain so long as ClassA (or anyone else) maintains a reference to them. – Slaw Jun 24 '18 at 23:12
  • No. As long as one object holds a reference to the elements, those elements will not be garbage collected. – markspace Jun 24 '18 at 23:12
  • Here's a similar question, note my answer where I point out that some objects may be incorrectly not garbage collected: https://codereview.stackexchange.com/questions/171862/java-stack-implementation/171921#171921 – markspace Jun 24 '18 at 23:14
  • @markspace : do you mean the "used" elements will not go away, but the List<> will go? – alsaleem Jun 24 '18 at 23:17
  • 1
    Yes, the elements that are still in use will remain, but any other object (like List<>) that doen't have a reference any more will (eventually) be garbage collected. – markspace Jun 24 '18 at 23:19
  • Clear. Thanks. How do I accept a comment as answer? Or could you move the comment to answer – alsaleem Jun 24 '18 at 23:29
  • A better idea would be to find another relevant Q&A and mark this as a duplicate of it. This question ... or something very similar ... has been asked many times before. (I'm busy at the moment.) – Stephen C Jun 25 '18 at 00:32

1 Answers1

0

The garbage collector deals in references to objects and its analysis will locate all objects that your code maintains references to.

To answer your three questions:

  1. If ClassA is still referenced by your code then any objects it references (regardless of which class created them) will not be collected.
  2. ClassB is out of scope, meaning it is no longer referenced by your code. It is therefore eligible of collection. When this happens is not defined.
  3. This question is not entirely clear. The collector will collect any objects that are not referenced (directly or indirectly).

To provide a bit more background to help you understand this. When common GCs (some may not do this) start they create what is called a root set. This is a list of all the objects that are directly accessible from your code. This is created by scanning all initialised classes (for static references) as well as the registers and stack. For CMS and G1 this root set is used to perform an initial marking phase (that executes concurrently with application threads). The collector will take each object reference in the root set and traverse all object references from that to build up a complete list of objects that can be accessed from your code. If an object is unreachable it will not be marked. Once marking is complete (for CMS and G1 this requires a stop-the-world remarking phase as well) the collector has a precise list of accessible objects.

For a young gen collection, the valid objects are copied into a survivor space or promoted to the old generation. Old gen collections will either update free lists for spaces between live objects or perform a full compacting collection, relocating objects to make them all contiguous in memory, eliminating fragmentation.

There are other algorithms that do things slightly differently (like C4 from Azul, who I work for) but the overall effect is the same.

Speakjava
  • 3,177
  • 13
  • 15