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