Start here. This is the direct spoken answer to practice first.
Why this question matters
Disposal defines deterministic ownership of sockets, streams, handles, timers, connections, and other resources that GC cannot release promptly. Finalization is a delayed safety net for low-level unmanaged ownership, not routine application cleanup.
IDisposable is for deterministic cleanup of resources when the owner is done with them. A finalizer runs later on the GC finalizer path and is mostly a safety net for types that directly own unmanaged resources. In normal application code, I prefer using statements, await using when needed, and clear ownership rules. I would not add a finalizer just because a class uses memory; memory is already handled by the GC.