Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Offheap leak after compiling with java 11

After upgrading our Spring web app maven build to Java 11 we see a constant increase in memory consumption from the java process.

Works fine: Build with Java 8 JDK + run on server with Java 11

Has leak: Build with Java 11 + run on server with Java 11

The leak is not visible in a heap dump or even Native Memory Tracking, the process keeps increasing until physical memory + swap is full and the process is killed by the system. What kind of issue could even be causing this kind of problem?

like image 873
Jeppz Avatar asked May 15 '20 12:05

Jeppz


People also ask

How do you fix a memory leak in Java?

Use reference objects to avoid memory leaks Using the java. lang. ref package, you can work with the garbage collector in your program. This allows you to avoid directly referencing objects and use special reference objects that the garbage collector easily clears.

Is memory leak possible in Java?

In general, a Java memory leak happens when an application unintentionally (due to logical errors in code) holds on to object references that are no longer required. These unintentional object references prevent the built-in Java garbage collection mechanism from freeing up the memory consumed by these objects.

How does Tomcat detect memory leaks in Java?

Go into the heap dump settings for your server Right-click on Tomcat from the sidebar on the left-hand side then select 'Heap Dump'. Figure 2: Heap Dump: Click on the 'OQL Console' button.


1 Answers

In Java 11 the ForkJoinPool class has a slightly different behaviour.

The default elapsed time since last use before a thread is terminated is 60 seconds. In Java 8 this was undocumented but actually hardcoded with 2 seconds. In case of oversized pools, the Java 8 implementation terminates idle threads two seconds after the pool was created. But the Java 9/11 version of the class keeps them alive for minutes.

Compare the number and lifetime of threads. Since unused threads may not be terminated early anymore when your application is started or ForkJoinPools objects are created the extended lifetime of threads could easily lead to a memory issue.

See the following question for a similar problem: ForkJoinPool performance Java 8 vs 11

In Java 9 a new constructor was introduced to configure the value. To get the same behavior as with Java 8 compilation, you have to set keepAliveTime explicitly to 2 seconds or reduce the size of your ForkJoinPool objects before you compile to Java 9.

like image 92
rmunge Avatar answered Nov 15 '22 00:11

rmunge