Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-7143743

(zipfs) Potential memory leak with zip provider

XMLWordPrintable

    • b06
    • x86
    • windows_7

        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

              lancea Lance Andersen
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: