I have read quite a bit on this topic lately, trying to make sense of it. What I found is:
Calling Dispose() does not free up the memory used by the object. Only the Garbage Collector does that. Dispose() is meant to release other resources
The Garbage Collector (GC) does not call Dispose(). It calls Finalize()
Dispose and Finalize are functionally separated, although you would normally want them to be linked. You normally want Dispose() to be called when an object is released from memory, even if you forgot to call it yourself.
Therefore it makes sense to create a Finalize() method, and to call Dispose() from it. And then it really makes sense to call SuppressFinalize() from Dispose(), to avoid that it is called twice.