In one of our applications, we create a large number of TimerTask objects to implement some "timeout" behavior in a long-running server application. When things are working normally, we wind up cancelling these tasks before the timeout occurs.
Our application was leaking memory like crazy. Upon inspection, we realized that when a TimerTask is cancelled, it isn't removed from the Timer heap, it's just marked for deletion. In our app, since no tasks were actually firing before they were cancelled, the queue was never examined and the (cancelled) tasks were never cleaned up.
It looks like Timer wasn't really designed to cope with creating and then subsequently cancelling large numbers of tasks. Perhaps a note about this implemention should be added to the javadoc so that people are aware of possible problems? Or maybe add a purge() method that would allow all the deadwood to be cleared from the timer queue?