-
Bug
-
Resolution: Fixed
-
P4
-
7, 8, 11, 13, 14, 15
-
b06
-
x86
-
windows_7
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8246763 | 13.0.4 | Lance Andersen | P4 | Resolved | Fixed | b05 |
JDK-8284534 | 11.0.16-oracle | Sean Coffey | P4 | Resolved | Fixed | b02 |
JDK-8237893 | 11.0.7 | Lance Andersen | P4 | Resolved | Fixed | b01 |
JDK-8237895 | openjdk8u252 | Lance Andersen | P4 | Resolved | Fixed | b02 |
FULL PRODUCT VERSION :
java version "1.7.0_02"
Java(TM) SE Runtime Environment (build 1.7.0_02-b13)
Java HotSpot(TM) Client VM (build 22.0-b10, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Versione 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
Writing a zip file using the ZipFileSystemProvider causes a memory leak; manipulating big zip files can lead to an OutOfMemoryError.
The test case shows that creating a new zip file and adding many files to it will lead to memory usage constantly growing; the memory will not be released even after the try-with-resources block is exited, closing the zip file.
Using the old ZipOutputStream/ZipEntry interface does not exhibit this behaviour.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.io.IOException;
import java.net.URI;
import java.nio.file.DirectoryStream;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
public class ZipLeak {
public static void main(String[] args) throws IOException {
Path origPath = FileSystems.getDefault().getPath("dirWithManyFiles");
Path zipFile1 = FileSystems.getDefault().getPath("newZipFile");
long javaMemory = 0;
try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(origPath);
FileSystem zipFS = createZipFileSystem(zipFile1, true)) {
Path zipRoot = zipFS.getPath("/");
for (Path path : dirStream) {
Files.copy(path, zipRoot.resolve(path.getFileName().toString()));
// print the used memory only after a garbage collection
long newJavaMemory = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
if (newJavaMemory < javaMemory) {
System.out.println(newJavaMemory);
}
javaMemory = newJavaMemory;
}
}
Runtime.getRuntime().gc();
System.out.println(javaMemory);
}
private static FileSystem createZipFileSystem(Path path, boolean create) throws IOException {
final URI uri = URI.create("jar:file:" + path.toUri().getPath());
final Map<String, String> env = new HashMap<>();
if (create) {
env.put("create", "true");
}
return FileSystems.newFileSystem(uri, env);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Do not use zipfs; use ZipOutputStream
java version "1.7.0_02"
Java(TM) SE Runtime Environment (build 1.7.0_02-b13)
Java HotSpot(TM) Client VM (build 22.0-b10, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Versione 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
Writing a zip file using the ZipFileSystemProvider causes a memory leak; manipulating big zip files can lead to an OutOfMemoryError.
The test case shows that creating a new zip file and adding many files to it will lead to memory usage constantly growing; the memory will not be released even after the try-with-resources block is exited, closing the zip file.
Using the old ZipOutputStream/ZipEntry interface does not exhibit this behaviour.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.io.IOException;
import java.net.URI;
import java.nio.file.DirectoryStream;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
public class ZipLeak {
public static void main(String[] args) throws IOException {
Path origPath = FileSystems.getDefault().getPath("dirWithManyFiles");
Path zipFile1 = FileSystems.getDefault().getPath("newZipFile");
long javaMemory = 0;
try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(origPath);
FileSystem zipFS = createZipFileSystem(zipFile1, true)) {
Path zipRoot = zipFS.getPath("/");
for (Path path : dirStream) {
Files.copy(path, zipRoot.resolve(path.getFileName().toString()));
// print the used memory only after a garbage collection
long newJavaMemory = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
if (newJavaMemory < javaMemory) {
System.out.println(newJavaMemory);
}
javaMemory = newJavaMemory;
}
}
Runtime.getRuntime().gc();
System.out.println(javaMemory);
}
private static FileSystem createZipFileSystem(Path path, boolean create) throws IOException {
final URI uri = URI.create("jar:file:" + path.toUri().getPath());
final Map<String, String> env = new HashMap<>();
if (create) {
env.put("create", "true");
}
return FileSystems.newFileSystem(uri, env);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Do not use zipfs; use ZipOutputStream
- backported by
-
JDK-8237893 (zipfs) Potential memory leak with zip provider
- Resolved
-
JDK-8237895 (zipfs) Potential memory leak with zip provider
- Resolved
-
JDK-8246763 (zipfs) Potential memory leak with zip provider
- Resolved
-
JDK-8284534 (zipfs) Potential memory leak with zip provider
- Resolved