Here's a good way to create a memory leak in pure Java:
-  a long-running thread  is created by the application
 
- The thread loads a class via an (optionally custom) ClassLoader
 
- The class allocates a large chunk of memory (e.g. new byte[1000000]), stores a strong reference to it in a static field, and then stores a reference to itself in a ThreadLocal
 
- Allocating the extra memory is optional, but it will make the leak work that much faster
 
- All references are cleared to the custom class or the ClassLoader  from which it was loaded
 
- Repeat
 
This works because the ThreadLocal keeps a reference to the object, which keeps a reference to its Class, which in turn keeps a reference to its ClassLoader. The ClassLoader, in turn, keeps a reference to all the Classes it has loaded