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

Java:如何高效地创建多个嵌套zip文件?,java,multithreading,zip,Java,Multithreading,Zip,我试图在多线程环境中创建几个zip文件(实际上,我试图使用一个服务于16个线程的FixedThreadPool ExecutorService编写大约400个zip文件)。每个zip文件可能包含数千个其他zip文件 不幸的是,大约两分钟后,我的java进程(Windows 64位上的jdk1.8.0_60_x64)似乎出现内存泄漏。虽然堆(根据Java任务控制)只使用了大约1GB(实际上在500MB和1GB之间),但Java进程总共使用了大约40GB的机器内存(似乎使用了很多本机内存)。当进程/

我试图在多线程环境中创建几个zip文件(实际上,我试图使用一个服务于16个线程的FixedThreadPool ExecutorService编写大约400个zip文件)。每个zip文件可能包含数千个其他zip文件

不幸的是,大约两分钟后,我的java进程(Windows 64位上的jdk1.8.0_60_x64)似乎出现内存泄漏。虽然堆(根据Java任务控制)只使用了大约1GB(实际上在500MB和1GB之间),但Java进程总共使用了大约40GB的机器内存(似乎使用了很多本机内存)。当进程/我的系统实际上停止工作时(我没有那么多内存),这个数字不断增加

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

  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();
    }
  }
publicstaticvoidmain(String[]args)抛出Throwable{
对于(int k=0;k<16;k++){
新线程(整数.toString(k)){
@凌驾
公开募捐{
试一试{
长字节=0;
ZipOutputStream zos=new-zipoutpstream(new-BufferedOutputStream(new-FileOutputStream)(新文件(getName()+“.tmp”)));
zos.setLevel(放气阀,无压缩);
Random rand=新的SecureRandom();
对于(int i=0;i<65535;i++){
zos.putNextEntry(新ZipEntry(“+i”);
ZipOutputStream inner=新的ZipOutputStream(zos);
对于(int j=0;j<10;j++){
字节[]b=新字节[512];
字节数+=b.length;
兰特下字节(b);
内.putNextEntry(新ZipEntry(“+j”);
写(b);
inner.closeEntry();
}
内表面处理();
内平齐();
zos.closeEntry();
zos.flush();
如果(i%1000==0){
System.err.println(getName()+“:“+i+”(“+bytes+”)bytes”);
}
}
zos.flush();
zos.close();
}
捕获(例外e){
e、 printStackTrace();
}
}
}.start();
}
}
我的代码有什么问题吗?可能吧

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

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