Java 档案是「;开放式;在列表中<;文件>;然后从记忆中消失

Java 档案是「;开放式;在列表中<;文件>;然后从记忆中消失,java,file,out-of-memory,Java,File,Out Of Memory,我在使用Java执行以下操作时遇到了一个问题: 在服务器上创建一个.xls文件并在其中写入一些内容 将此文件存储到列表中 重复第1步和第2步数千次,得到一个包含数千个.xls文件的列表 将文件导出到.zip存档中 我的问题是,创建的文件似乎都是“打开”的,并且内存不足。实际上,每个文件只有大约37KB,文件数量只有大约2000个。我觉得不算太多,但每次都失败了。有人知道这个问题吗?非常感谢你 问题是,你的过程走错了方向。ZIP文件不是通过将每个文件读入内存、压缩然后写入输出来构建的。相反,它一次

我在使用Java执行以下操作时遇到了一个问题:

  • 在服务器上创建一个.xls文件并在其中写入一些内容
  • 将此文件存储到列表中
  • 重复第1步和第2步数千次,得到一个包含数千个.xls文件的列表
  • 将文件导出到.zip存档中

  • 我的问题是,创建的文件似乎都是“打开”的,并且内存不足。实际上,每个文件只有大约37KB,文件数量只有大约2000个。我觉得不算太多,但每次都失败了。有人知道这个问题吗?非常感谢你

    问题是,你的过程走错了方向。ZIP文件不是通过将每个文件读入内存、压缩然后写入输出来构建的。相反,它一次只写一个文件,只有目录列表存储在内存中。在伪代码中,这意味着您正在执行以下操作:

    Create Zip Memory Directory
    Open Zip File Handle
    For Each File In Directory
        Open File In Read Mode
        Compress File
        Write Headers and File To Zip File
        Store Info About File in Zip Memory Directory
        Close File
    End For
    Write Zip Memory Directory to Zip File
    Close Zip File Handle
    
    这意味着您只需要压缩单个文件所需的内存,并且在任何给定时间只打开两个文件。这在一定程度上是因为大多数系统跟踪打开文件的空间(“句柄”)有限,因此根据语言/操作系统/任何东西的不同,您可能会耗尽平台对每个线程/进程/整个系统的文件句柄限制。类似地,解压缩也通常一次实现一个文件

    在Java中,您实际上很可能正在使用一个Zip实用程序类,读取每个文件,将其压缩到内存中的某个位置,然后关闭该文件,并循环处理剩余的文件;在整个过程结束时,将Zip文件保存到磁盘


    请参阅一个您可以使用的类。实际上,它的工作原理是接受一个OutputStream(通过在写模式下打开一个文件创建),然后在循环中调用putnextery、write、closeEntry,最后调用close()将文件刷新到磁盘。

    您应该提供您得到的实际错误和代码的代表性示例。37k*2000=74兆字节。这并不是“很多”,但它肯定是一个很大的记忆,在同一时间举行。你的应用程序需要内存才能运行。如何配置此应用程序的内存参数?你是否给了应用程序至少几GB的运行空间?你没有发布实际的错误消息,我怀疑你的文件句柄不足,而不是内存不足。