0

Memory leak in JVM_StartThread with the integration of Virtual threads

 1 year ago
source link: https://bugs.openjdk.org/browse/JDK-8296463
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

[JDK-8296463] Memory leak in JVM_StartThread with the integration of Virtual threads

Details

Backports

Issue Fix Version Assignee Priority Status Resolution Resolved In Build
JDK-8297690 19.0.2  David Holmes P4 Resolved Fixed b07

Description

ADDITIONAL SYSTEM INFORMATION :
Microsoft Windows [Version 10.0.19044.2006]

openjdk version "19.0.1" 2022-10-18
OpenJDK Runtime Environment (build 19.0.1+10-21)
OpenJDK 64-Bit Server VM (build 19.0.1+10-21, mixed mode, sharing)

A DESCRIPTION OF THE PROBLEM :
See https://youtrack.jetbrains.com/issue/IDEA-305072 for a related discussion.

The attached testcase runs fine without a debugger, but if you run it in debug mode the JVM will get progressively slower until ~2 hours later the JVM will hang indefinitely.

Sometimes the hang is so bad that jstack and jmap will refuse to connect (they are probably unable to spawn a new thread).

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Start a debugging session of the attached testcase:
2. About 2 hours - 2:30 hours later, output will cease and the JVM will hang indefinitely.
3. If you run the same testcase without a debugging session, it will not hang.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
There are about 500 live threads running at a time and no threads or memory seem to be leaking (as far as VisualVM seems to show), so I am not expecting a hang or a crash.
ACTUAL -
JVM hangs. Often when this happens, jstack (and related tools) cannot attach to probe the state of the JVM.

---------- BEGIN SOURCE ----------
pom.xml:
----------------------------
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>org.example</groupId>
<artifactId>ThreadsHang</artifactId>
<version>1.0-SNAPSHOT</version>

<properties>
<maven.compiler.release>19</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.3</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.4.4</version>
<exclusions>
<exclusion>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<showWarnings>true</showWarnings>
<showDeprecation>true</showDeprecation>
<compilerArgs>
<arg>-Xlint:all,-preview,-try</arg>
<arg>-Xdiags:verbose</arg>
<arg>-Werror</arg>
<arg>--enable-preview</arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
</project>

PlatformThreadsTestcase:
---------------------------------------
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.LongAdder;

public class PlatformThreadsTestcase
{
private final ThreadFactory blockingTasksThreadFactory = new ThreadFactoryBuilder().
setNameFormat("BlockingTask-%d").
build();
private final ExecutorService blockingTasksExecutor = Executors.newThreadPerTaskExecutor(
blockingTasksThreadFactory);
private final Logger log = LoggerFactory.getLogger(PlatformThreadsTestcase.class);

public static void main(String[] args) throws InterruptedException
{
PlatformThreadsTestcase testcase = new PlatformThreadsTestcase();
testcase.run();
}

public void run() throws InterruptedException
{
Semaphore semaphore = new Semaphore(500);
LongAdder adder = new LongAdder();
while (true)
{
semaphore.acquire();
blockingTasksExecutor.submit(() ->
{
adder.increment();
long sum = adder.sum();
if ((sum % 1000) == 0)
log.info("Progress: {}", sum);
try
{
Thread.sleep(50);
}
catch (InterruptedException e)
{
throw new RuntimeException(e);
}
finally
{
semaphore.release();
}
});
}
}
}
---------- END SOURCE ----------

FREQUENCY : always

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK