Java:如何有效地创建多个嵌套的zip文件?

时间:2016-03-16 16:41:30

标签: java multithreading zip

我正在尝试在多线程环境中创建多个zip文件(实际上我尝试使用提供16个线程的FixedThreadPool ExecutorService来编写大约400个zip文件)。每个zip文件都可能包含数千个其他zip文件。

不幸的是,大约两分钟后,我的java进程(Windows 64bit上的jdk1.8.0_60_x64)似乎最终导致内存泄漏。虽然堆(根据Java Mission Control)仅使用大约1 GB(实际上在500 MB和1 GB之间),但java进程总共使用大约40 GB的机器内存(似乎使用了大量本机内存)。当进程/我的系统几乎停止工作时(我没有那么多内存),这个数字不断增加并且接着不断增加。

经过一些研究后,我发现可以使用一个相当小的主要方法来模拟行为:

  public static void main(String[] args) throws Throwable {
    for (int k = 0; k < 16; k++) {
      new Thread(Integer.toString(k)) {
        @Override
        public void run() {
          try {
            long bytes = 0;
            ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(new File(getName() + ".tmp"))));
            zos.setLevel(Deflater.NO_COMPRESSION);
            Random rand = new SecureRandom();
            for (int i = 0; i < 65535; i++) {
              zos.putNextEntry(new ZipEntry("" + i));
              ZipOutputStream inner = new ZipOutputStream(zos);
              for (int j = 0; j < 10; j++) {
                byte[] b = new byte[512];
                bytes += b.length;
                rand.nextBytes(b);
                inner.putNextEntry(new ZipEntry("" + j));
                inner.write(b);
                inner.closeEntry();
              }
              inner.finish();
              inner.flush();
              zos.closeEntry();
              zos.flush();
              if (i % 1000 == 0) {
                System.err.println(getName() + ": " + i + " (" + bytes + ") bytes");
              }
            }
            zos.flush();
            zos.close();
          }
          catch (Exception e) {
            e.printStackTrace();
          }
        }
      }.start();
    }
  }

我的代码有什么问题吗?可能。

  • 在这么多线程中使用I / O操作是个坏主意吗?我真的不确定(实际上我想获得性能,而不是松散的性能)。但另一方面,如果我省略了所有的zip内容,只需在更多线程中写入FileOutputStream就不会出现这样的问题。 zip压缩条目的开销会增加那么多吗?

  • 使用内部 ZipOutputStream有什么问题吗?据我所知,我不能为这个类调用close(),因为它也会关闭名为 zos 的外部流。相反,我打电话给 finish()

0 个答案:

没有答案