2

How does Java's garbage collector differentiate primitives and references on the operand stack?

If my understanding is correct, this code "someFunction(0, new SomeClass())" would result in a primitive integer 0 and a reference to a new instance of type SomeClass being pushed to the operand stack. Further, the only reference to the new instance would be on the operand stack, so the gc would have to traverse the operand stack to find live references. It is not clear to me how the gc could efficiently determine the types of the values on the operand stack (which are references and which are just numeric values). All strategies that occur to me seem inefficient, such as examining the bytecode + instruction pointer to determine the types of values on the operand stack or tracking the values of types on the operand stack in some structure.

This is NOT a duplicate of "Is the stack garbage collected in Java?". The answer to the question "is the stack garbage collected in java" is no, because stack frames are popped when functions return. Primitives stored in stack frames are not in the heap, they would be referred to as having auto storage duration in C. However, references stored in the operand stack should keep the objects to which they refer alive. Thus, the operand stack contains both primitive numeric values and references. The references must be traversed during tracing gc, but primitives should be ignored since their memory is freed when a call returns.

T. Riddle
  • 21
  • 4
  • 1
    The stack is not garbage collected. – shmosel Sep 14 '18 at 23:00
  • I don't really get the question. The JVM creates the stack frame. Why wouldn't it know what's in it? – shmosel Sep 14 '18 at 23:25
  • @shmosel, my question is how the gc *efficiently* traverses references in the operand stack during a trace. Obviously the types of operands on the stack can be determined by looking at the bytecode + ip, but this seems like it might be too tedious/slow to be practical (I could be wrong, hopefully someone will answer that). As an example, if I allocate several buffers and fill them with numbers and memory addresses, I would have to retrace my steps to determine whether an index contains and address or primitive number if I didn't tag the values or store type information in some structure. – T. Riddle Sep 14 '18 at 23:35
  • @ErwinBolwidt, thanks, I think that is closer to what I'm looking for. Also, https://stackoverflow.com/questions/8481602/garbage-collection-root-nodes/12097214 seems closer to my question. – T. Riddle Sep 14 '18 at 23:47
  • I guess, the proper answer is [this one](https://stackoverflow.com/a/39435437/581205), but I'm no expert. Anyway, there're multiple GCs and each may work differently as there's no perfect solution. The accepted answer has quite [some problems](https://stackoverflow.com/questions/8481602/garbage-collection-root-nodes/12097214#comment91628627_12097214). – maaartinus Sep 15 '18 at 01:20
  • HotSpot JVM uses **OopMaps** to find references on the stack. See [this answer](https://stackoverflow.com/a/26049445/3448419) for details. – apangin Sep 15 '18 at 11:29
  • The stack frame for the method records where on the stack the references are. – Peter Lawrey Sep 15 '18 at 11:51
  • The real question is: how does the garbage collector update the references pushed to the operand stack when moving an object in heap? – neoexpert Mar 03 '20 at 16:15

0 Answers0