How Fork Join Pool caused Memory Leak!!

Naga Hemanth Kotha
3 min readFeb 14, 2021

I’m one of those person who is crazy about parallel streams and functional programming ,before I faced this memory leak I always thought that “Why don’t people use parallel streams everywhere?” you know with just one line .parallel() you can make your code run parallel and fast

Are you thinking the same? then you are wrong!!

First thing parallel streams uses common pool so If you are thinking that using parallel streams everywhere will make your code run faster you are wrong. After certain number of tasks given to common pool based on the cores in that system it becomes blocking and also remember that java uses common pool internally,so you cant use parallel streams everywhere and think that it will be faster

After learning this I looked for ways around that and I found out that we can make custom forkjoin pools and assign our parallel streams to those pools.While creating the pool we know that how many threads we need and parallelism we need etc and based on that we can create them

So after seeing this I made a Fork-Join pool and I used it in my code like below.

public void someName(){
ForkJoinPool forkJoinPool = new ForkJoinPool();
return forkJoinPool.submit(() -> rootIds.parallelStream()
.map(this::getById)
.collect(Collectors.toList())).get();}

If you already got what I did wrong then my friend you can leave from the blog

Bye Bye!

For all the others like me well my friends The idea of fork join pool is that once the tasks given to fork join pool are over and when the instance went out of scope the threads that are created by the pool won’t just get dereferenced for the Garbage collector to clean them, they will be waiting for more tasks to be given.So for every req I make to that function someName() I will be filling my heap memory.So if you want to see my case this is how my metrics look like

you see that the memory went on increasing when I did load testing and after analysing the heap dump I found out that its fork join pool that's causing the issue.Using Jprofiler you can even see the waiting threads increase as you hit that function more

Solution

So the solution is pretty easy so you either shutdown the fork join pool using .shutdown() function before exiting that function or you make a utility class and make static fork join pool to make sure that you use one pool all the time but here also if you are using the same pool everywhere then its commonpool all over again so that is how I got a memory leak because of Forkjoin pool and How I solved it

Happy Coding :)

--

--