Let's say it is a concurrent mark-and-sweep garbage collector.
When such GC handles constant pointers it just walks through them (starting from roots), and marks every encountered data block. Then sweeps everything unmarked. A client code should mark the data blocks it uses as roots.
But what to do with variables? Here is a situation:
Vis a variable, which stores a pointer to object
Vand makes it point to object
- The garbage collector runs its "mark" phase and encounters that
Ais no longer referenced, then deallocates it during the "sweep" phase.
Thread 1awakens and tries to use
A(already read from
Vat step 2) by marking it as root. And fails, because
Ais no longer exists.
So, how to handle this?
Thread 2 can mark the replaced object
A with a special do-not-remove flag (similar flag is used for newly allocated objects). But when this flag should be removed? Of course
Thread 1 could do that. But
Thread 2 knows nothing about
Thread 1, and thus can not be sure that this will be done ever. This may lead to
A will never be freed. And if GC will remove that flag, then nothing prevents
A from being removed when GC runs for the second time...
The on-the-fly mark-and-sweep garbage collector descriptions I've read just mention that the replaced object should be "grayed". But without any specifics. A link to a more detailed description of the solution would be highly appreciated.