Hi Michael,
The DockSite.WindowsClosed event fires when the docking windows are hidden and removed from the layout (such as when the user clicks the close button in a tool window's title bar), but not necessarily when they are permanently destroyed. As such, I would not recommend calling your view-model's Dispose method from that event handler, because if the tool window is reopened, the same view-model would be used that is now disposed.
For your case, the DockSite.WindowUnregistered event is what is called after a tool window is closed AND it has been "destroyed", which means is being disassociated with the DockSite. That is the place you'd want to call a view-model Dispose method. You can read more about that in this documentation topic.
Note that tool windows do not destroy themselves when they are closed, but document windows DO destroy themselves on close by default. This is due to document windows generally having a different lifecycle than tool windows. That default can be changed if you wish, based on information in the same linked documentation topic.