-
Bug
-
Resolution: Fixed
-
P3
-
8, 11
-
b01
-
generic
-
generic
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8315408 | 11.0.21 | Volker Simonis | P3 | Resolved | Fixed | b06 |
JDK-8315547 | openjdk8u402 | Volker Simonis | P3 | Resolved | Fixed | b01 |
JDK-8318381 | openjdk8u392 | Volker Simonis | P3 | Resolved | Fixed | b08 |
The native implementation of the `Pack200.Unpacker` class included in OpenJDK 8 and 11 has a native and heap memory leak that gets triggered when corrupted files are processed. If the native `NativeUnpack::start()` method throws an exception (because of a corrupted input file) its caller `NativeUnpack::run()` fails to call the native `NativeUnpack::finish()` method which is responsible for freeing the allocated native memory and releasing the created global JNI handles. A Java application processing large number of corrupted Pack200 files will eventually run either out of native memory or out of heap space and exit with an `OutOfMemoryError`.
The problem can be demonstrated with the following short test program which will exit with an `OutOfMemoryError` quite quickly if run with `java -Xmx32m NativePack200POC`:
```
import java.io.*;
import java.util.jar.*;
@SuppressWarnings("removal")
public class NativePack200POC {
public static void main(String[] args) {
try {
ByteArrayInputStream in = new ByteArrayInputStream("foobar".getBytes());
for(int i=0; i < 1_000_000; i++) {
try {
JarOutputStream out = new JarOutputStream(new ByteArrayOutputStream());
Pack200.Unpacker unpacker = Pack200.newUnpacker();
unpacker.unpack(in, out);
} catch (IOException e) {
}
}
} catch (OutOfMemoryError e) {
System.out.println(e);
throw e;
}
}
}
```
The problem can be worked around by disabling the native Pack200 implementation with `-Dcom.sun.java.util.jar.pack.disable.native=true` but the default setting is `-Dcom.sun.java.util.jar.pack.disable.native=false`.
Notice that this bug can not be fixed in HEAD because the Pack200 functionality has been removed in JDK 14 (https://openjdk.org/jeps/367). I therefore propose to fix this in jdk11u-dev first and then downport the fix to jdk8u-dev as well.
- backported by
-
JDK-8315408 Memory leak in the native implementation of Pack200.Unpacker.unpack()
- Resolved
-
JDK-8315547 Memory leak in the native implementation of Pack200.Unpacker.unpack()
- Resolved
-
JDK-8318381 Memory leak in the native implementation of Pack200.Unpacker.unpack()
- Resolved
- links to
-
Commit openjdk/jdk8u-dev/6632d0a7
-
Commit openjdk/jdk11u-dev/b77c161e
-
Commit openjdk/jdk11u/14fa970e
-
Review openjdk/jdk8u-dev/361
-
Review openjdk/jdk11u-dev/2100
-
Review openjdk/jdk11u/79