压缩-java.lang.OutOfMemoryError:java堆空间
我有这段代码来压缩文件夹,但是当我压缩大文件夹(10GB)时,我的内存出现了一个错误。它适用于1GB左右的文件夹 可能是内存泄漏,但在我的代码中泄漏在哪里?我怎样才能解决这个问题 谢谢 这就是错误:压缩-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
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()需要在返回它之前建立一个包含所有文件名的数组。