Is it really able to handle all objects that aren't used
No, it can't. It can, however, collect all objects which cannot be used anymore, and it does that very well. The difference is subtle, see below.
Explanation
For example, say you have the following code:
class A {
public static Date d = new Date(); // d will never be collected
}
And let's say you know that after a certain time d
will never be accessed again. The runtime system doesn't have that information, though, and d
will be kept alive indefinitely, while in C++ you could explicitly delete it.
Instead, the garbage collector collects all objects that are no longer accessible. For instance:
void f() {
Date d = new Date();
System.out.println(d.toString());
} // d is no longer accessible at this point
The garbage collector detects that there is no way the object that d
references will ever be accessed again, as d
is its only reference and it goes out of scope at the end of the method. Collecting non-accessible objects is an under-estimation of the "what objects can be collected" question, but it's safe because it guarantees no live object will ever be collected.
The difference is subtle and indeed, in most sane code, all the objects that you no longer use will be collected. That collection itself is complete, able to correctly identify and collect every non-accessible object, and that includes objects which are not accessible because all their references reside in other non-accessible objects.