压缩-java.lang.OutOfMemoryError:java堆空间

压缩-java.lang.OutOfMemoryError:java堆空间,java,memory,zip,Java,Memory,Zip,我有这段代码来压缩文件夹,但是当我压缩大文件夹(10GB)时,我的内存出现了一个错误。它适用于1GB左右的文件夹 可能是内存泄漏,但在我的代码中泄漏在哪里?我怎样才能解决这个问题 谢谢 这就是错误: Exception in thread "main" java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.N

我有这段代码来压缩文件夹,但是当我压缩大文件夹(10GB)时,我的内存出现了一个错误。它适用于1GB左右的文件夹

可能是内存泄漏,但在我的代码中泄漏在哪里?我怎样才能解决这个问题

谢谢

这就是错误:

Exception in thread "main" java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at     sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:56)
Caused by: java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:2882)
at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:100)
at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:572)
at java.lang.StringBuilder.append(StringBuilder.java:203)
at java.io.UnixFileSystem.resolve(UnixFileSystem.java:93)
at java.io.File.<init>(File.java:207)
at java.io.File.listFiles(File.java:1056)
at Zipper.addDir(Zipper.java:27)
at Zipper.addDir(Zipper.java:32)
at Zipper.addDir(Zipper.java:32)
at Zipper.addDir(Zipper.java:32)
at Zipper.addDir(Zipper.java:32)
at Zipper.addDir(Zipper.java:32)
at Zipper.addDir(Zipper.java:32)
at Zipper.addDir(Zipper.java:32)
at Zipper.addDir(Zipper.java:32)
at Zipper.zipDir(Zipper.java:17)
at Schedule.runBackup(Schedule.java:128)
at Machine.runBackup(Machine.java:108)
at Person.main(Person.java:51)
线程“main”java.lang.reflect.InvocationTargetException中的异常 在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处 位于sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)中 位于java.lang.reflect.Method.invoke(Method.java:597) 位于org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:56) 原因:java.lang.OutOfMemoryError:java堆空间 位于java.util.Arrays.copyOf(Arrays.java:2882) 位于java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:100) 位于java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:572) 在java.lang.StringBuilder.append处(StringBuilder.java:203) 位于java.io.UnixFileSystem.resolve(UnixFileSystem.java:93) 位于java.io.File。(File.java:207) 位于java.io.File.listFiles(File.java:1056) at zippers.addDir(zippers.java:27) at zippers.addDir(zippers.java:32) at zippers.addDir(zippers.java:32) at zippers.addDir(zippers.java:32) at zippers.addDir(zippers.java:32) at zippers.addDir(zippers.java:32) at zippers.addDir(zippers.java:32) at zippers.addDir(zippers.java:32) at zippers.addDir(zippers.java:32) at zippers.zipDir(zippers.java:17) at Schedule.runBackup(Schedule.java:128) 运行备份(Machine.java:108) 在Person.main(Person.java:51) 代码如下:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import javax.swing.JFrame;
import javax.swing.JOptionPane;

public class Zipper {

static void zipDir(String zipFileName, String dir) throws Exception {
    File dirObj = new File(dir);
    try {
        ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFileName));
        addDir(dirObj, out);
        out.close();    
    } catch(Exception e) {
        JFrame frame = new JFrame();
        JOptionPane.showMessageDialog(frame, e.getMessage() + ". Is settings.xml correct?");
    }
}

static void addDir(File dirObj, ZipOutputStream out) throws IOException {
    try {
        File[] files = dirObj.listFiles();
        byte[] tmpBuf = new byte[1024];
        for (int i = 0; i < files.length; i++) {
            try {
                if (files[i].isDirectory()) {
                    addDir(files[i], out);
                    continue;
                }
                FileInputStream in = new FileInputStream(files[i].getAbsolutePath());
                out.putNextEntry(new ZipEntry(files[i].getAbsolutePath().replace(File.separatorChar,'/')));
                int len;
                while ((len = in.read(tmpBuf)) > 0) {
                    try {
                        out.write(tmpBuf, 0, len);
                    }
                    catch(Exception e) {
                        System.out.println(e.getMessage());
                    }
                }   
                out.closeEntry();
                in.close();
            }
            catch(Exception e) {
                System.out.println(e.getMessage());
            }
        }
    }
    catch(Exception e) {
        System.out.println(e.getMessage());
    }
}
}
导入java.io.File;
导入java.io.FileInputStream;
导入java.io.FileOutputStream;
导入java.io.IOException;
导入java.util.zip.ZipEntry;
导入java.util.zip.ZipoutStream;
导入javax.swing.JFrame;
导入javax.swing.JOptionPane;
公营拉链{
静态void zipDir(字符串zipFileName,字符串dir)引发异常{
File dirObj=新文件(dir);
试一试{
ZipOutputStream out=newzipoutpstream(newfileoutputstream(zipFileName));
addDir(dirObj,out);
out.close();
}捕获(例外e){
JFrame=新JFrame();
showMessageDialog(框架,例如getMessage()+”。settings.xml正确吗?);
}
}
静态void addDir(文件dirObj,ZipOutputStream out)引发IOException{
试一试{
File[]files=dirObj.listFiles();
字节[]tmpBuf=新字节[1024];
对于(int i=0;i0){
试一试{
out.write(tmpBuf,0,len);
}
捕获(例外e){
System.out.println(e.getMessage());
}
}   
out.closeEntry();
in.close();
}
捕获(例外e){
System.out.println(e.getMessage());
}
}
}
捕获(例外e){
System.out.println(e.getMessage());
}
}
}

如前所述,检查堆大小,尽管如果1GB正常,可能会将堆大小设置得足够高。 考虑到您要处理10GB的未压缩数据,请不要忘记zip格式的限制:归档文件的最大大小为4GB(如果您不使用zip64)。我不知道这和你的案子有没有关系,但可能就是这样


作为旁注,始终
close()


但是,您的问题可能不是泄漏。你的目录有多大?异常发生在listFiles中,因此如果您有一个非常大的目录(或者一组目录,因为您使用的是递归遍历),那么可能您的文件太多了。正如@CoolBeans所说,您可能只需要调整堆空间参数。

您的jdk版本是什么?我问的原因是JDK1.4中有一个问题。太多的数据应该不是问题,因为他使用了
FileOutputStream
,流没有保存在内存中。但也许他有大量的文件,不知怎么的,它突然出现……这就是我的意思;我已经编辑了我的帖子,以防其他人感到困惑。感谢您指出这一点。对于listFiles(),数据的大小无关紧要,但文件的数量却无关紧要。如果目录中有很多小文件,这将触发OOME,而不管它们的大小,因为listFiles()需要在返回它之前建立一个包含所有文件名的数组。