Clearly you are used to a reference counting solution to determining garbage. In reference counting, circular references are an issue because each one keeps the other alive.
(It’s worth noting though that even in your car-engine case above, as soon as you break one link in the circle, its not a problem. Car references Engine. Engine references car. That will stay around in reference counting situation because both objects have a count of one. if however you null Car’s reference to Engine, Engines count drops to 0. Engine is freed. When Engine is free ITS reference to Car goes away so Car’s count drops to 0 and Car is also freed.)
HOWEVER reference counting is a very primitive soulutions for garbage detection. More sophisticated solutions (such as used by Java) actually trace reference trees back to “root” objects that process can start a reference chain from (eg static variables, class variables, instance variables or temporary variables currently active on the stack.) If the object is not reachable from one of them, it is marked as garbage and eventually collected.
In your earlier example, if Car or Engine were an object instance variable then both would stay HOWEVER if your object instance contained a list of cars, that was the only “root” reference to Car, there were no “root” references to Engine except through Car, and you removed Car from the List, Car AND Engine would get marked as garbage and, should the need for memory arise, collected.
See?