Why is the object destructor paradigm in garbage collected languages pervasively absent?
The pattern you're talking about, where objects know how to clean their resources up, falls into three relevant categories.  Let's not conflate destructors with finalizers - only one is related to garbage collection:

The finalizer pattern: cleanup method declared automatically, defined by programmer, called automatically.
Finalizers are called automatically before deallocation by a garbage collector.  The term applies if the garbage collection algorithm employed can determine object life cycles.

The destructor pattern: cleanup method declared automatically, defined by programmer, called automatically only sometimes.
Destructors can be called automatically for stack-allocated objects (because object lifetime is deterministic), but must be explicitly called on all possible execution paths for heap-allocated objects (because object lifetime is nondeterministic).

The disposer pattern: cleanup method declared, defined, and called by programmer.
Programmers make a disposal method and call it themselves - this is where your custom myObject.destroy() method falls.  If disposal is absolutely required, then disposers must be called on all possible execution paths.


Finalizers are the droids you're looking for.
The finalizer pattern (the pattern your question is asking about) is the mechanism for associating objects with system resources (sockets, file descriptors, etc.) for mutual reclamation by a garbage collector. But, finalizers are fundamentally at the mercy of the garbage collection algorithm in use.
Consider this assumption of yours:

Languages which offer automatic garbage collection ... know with 100% certainty when an object is no longer in use.

Technically false (thank you, @babou).  Garbage collection is fundamentally about memory, not objects.  If or when a collection algorithm realizes an object's memory is no longer in use depends on the algorithm and (possibly) how your objects refer to each other.  Let's talk about two types of runtime garbage collectors.  There are lots of ways to alter and augment these to basic techniques:

Tracing GC.  These trace memory, not objects.  Unless augmented to do so, they don't maintain back references to objects from memory.  Unless augmented, these GCs won't know when an object can be finalized, even if they know when its memory is unreachable.  Hence, finalizer calls aren't guaranteed.

Reference Counting GC. These use objects to track memory.  They model object reachability with a directed graph of references.  If there is a cycle in your object reference graph, then all objects in the cycle will never have their finalizer called (until program termination, obviously).  Again, finalizer calls are not guaranteed.


TLDR
Garbage collection is difficult and diverse.  A finalizer call cannot be guaranteed before program termination.