java.lang.OutOfMemoryError:java堆空间没有更多空间
我不知道我为什么会犯这个错误。我找不到任何方法来保存更多的内存。如果有人能帮我提高效率,我将不胜感激。 有人能检查一下我的代码,看看我做了什么傻事吗?提前谢谢 主类java.lang.OutOfMemoryError:java堆空间没有更多空间,java,out-of-memory,Java,Out Of Memory,我不知道我为什么会犯这个错误。我找不到任何方法来保存更多的内存。如果有人能帮我提高效率,我将不胜感激。 有人能检查一下我的代码,看看我做了什么傻事吗?提前谢谢 主类 import java.awt.BorderLayout; import java.awt.EventQueue; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import javax.swing.JFram
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.SpringLayout;
import javax.swing.JTextField;
import javax.swing.JTextArea;
import javax.swing.JScrollPane;
import javax.swing.JButton;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class Main extends JFrame {
private JPanel contentPane;
private JTextField Searchq;
private JScrollPane scrollPane;
private static JTextArea txtpdisplay;
/**
* Launch the application.
*
* @throws IOException
*/
public static void filelistandfind(String find) throws IOException {
Files.walk(Paths.get("C:\\Users\\localness\\Desktop\\Locker")).forEach(
filePath -> {
if (Files.isRegularFile(filePath)) {
if (filePath.toString().endsWith(".docx")) {
try {
if (DocxCompair.Readfile(filePath.toString(),
find)) {
//System.out.println(filePath);
txtpdisplay.append(filePath.toString() + "\n");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Main frame = new Main();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public Main() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 646, 344);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
SpringLayout sl_contentPane = new SpringLayout();
contentPane.setLayout(sl_contentPane);
Searchq = new JTextField();
sl_contentPane.putConstraint(SpringLayout.NORTH, Searchq, 5,
SpringLayout.NORTH, contentPane);
sl_contentPane.putConstraint(SpringLayout.WEST, Searchq, 108,
SpringLayout.WEST, contentPane);
sl_contentPane.putConstraint(SpringLayout.SOUTH, Searchq, 36,
SpringLayout.NORTH, contentPane);
contentPane.add(Searchq);
Searchq.setColumns(10);
scrollPane = new JScrollPane();
sl_contentPane.putConstraint(SpringLayout.NORTH, scrollPane, 3, SpringLayout.SOUTH, Searchq);
sl_contentPane.putConstraint(SpringLayout.WEST, scrollPane, 5, SpringLayout.WEST, contentPane);
sl_contentPane.putConstraint(SpringLayout.SOUTH, scrollPane, -9, SpringLayout.SOUTH, contentPane);
sl_contentPane.putConstraint(SpringLayout.EAST, scrollPane, -5, SpringLayout.EAST, contentPane);
sl_contentPane.putConstraint(SpringLayout.EAST, Searchq, 0,
SpringLayout.EAST, scrollPane);
contentPane.add(scrollPane);
txtpdisplay = new JTextArea();
txtpdisplay.setText("");
scrollPane.setViewportView(txtpdisplay);
JButton Search = new JButton("Search");
Search.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent arg0) {
try {
filelistandfind(Searchq.getText());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
sl_contentPane.putConstraint(SpringLayout.NORTH, Search, 2, SpringLayout.NORTH, Searchq);
sl_contentPane.putConstraint(SpringLayout.WEST, Search, 0, SpringLayout.WEST, scrollPane);
sl_contentPane.putConstraint(SpringLayout.SOUTH, Search, -3, SpringLayout.SOUTH, Searchq);
sl_contentPane.putConstraint(SpringLayout.EAST, Search, -6, SpringLayout.WEST, Searchq);
contentPane.add(Search);
}
}
DocxCompair类
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Paths;
import java.util.zip.ZipInputStream;
public final class DocxCompair {
private static byte[] buffer = new byte[204800];
private static String result;
private static int len;
/*
* public static void main(String[] args) throws IOException { String s =
* "Stuart.docx"; String n = "<#tag>"; FileInputStream is = new
* FileInputStream(s); ZipInputStream zis = new ZipInputStream(is);
* System.out.println(Readfile(s, n)); }
*/
private static boolean extractFile(ZipInputStream zipIn, String filePath,
String text) throws IOException {
result = "";
len = 0;
while ((len = zipIn.read(buffer)) > 0) {
// System.out.print(new String(buffer));
System.gc();
result += result + new String(buffer);
}
// System.out.println();
if (result.contains(text)) {
return true;
} else {
return false;
}
}
private static String texttag;
private static String fileName;
private static ZipInputStream zip;
public static boolean Readfile(String names, String text)
throws FileNotFoundException {
// TODO Auto-generated method stub
fileName = names;
zip = new ZipInputStream(new FileInputStream(fileName));
try {
String name;
while (true) {
try {
name = zip.getNextEntry().getName();
// System.out.println(name);
if (name.startsWith("word/document.xml")) {
// System.out.println(name);
texttag = text;
texttag = texttag.replace(">", ">");
texttag = texttag.replace("<", "<");
// System.out.println(texttag);
if (extractFile(zip, name, texttag)) {
return true;
} else {
return false;
}
}
} catch (NullPointerException a) {
// a.printStackTrace();
return false;
// break;
}
}
// System.out.println("Done");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
}
}
}
你在建造一条巨大的绳子。查看您的代码:
result = "";
len = 0;
while ((len = zipIn.read(buffer)) > 0) {
// System.out.print(new String(buffer));
System.gc();
result += result + new String(buffer);
}
假设我一次读取2个字节。下面是这段代码发生的情况
result = ab // empty + empty + new stuff
result = ababcd // result + result + new stuff.
result = ababcdababcdef // result + result + new stuff
result = ababcdababcdefababcdababcdefgh // result + result + new stuff
每次你读到一块200k的内容时,你会把结果的大小增加一倍,然后再加上200k。这意味着对于2mb文件(200k的10次读取),您的结果实际上刚刚超过204mb。
原因是您正在执行result+=result+新字符串(缓冲区)代码>
您应该执行result+=新字符串(缓冲区)
或者,最好使用StringBuffer并在阅读时附加到它
StringBuffer result = new StringBuffer();
len = 0;
while ((len = zipIn.read(buffer)) > 0 ) {
result.append( new String(buffer));
}
首先,您没有正确地关闭所有资源
第二,有几件事你可以试试
首先,您可以使用一个名为Files.find()
的方法。试试这个:
private static final BiPredicate<Path, BasicFileAttributes> DOCX_FILES
= (path, attrs) -> attrs.isRegularFile
&& path.getFileName().toString().endsWith(".docx");
final Path basePath = Paths.get("C:\\Users\\localness\\Desktop\\Locker");
try (
final Stream<Path> stream = Files.find(basePath, Integer.MAX_VALUE, DOCX_FILES);
) {
stream.forEach(path -> whatever)
}
为什么要使用文件
?此外,您还可以使用zip文件系统提供程序如何执行此代码?如果它在IDE中运行,尝试提供更多的HeapSpace这是一个“漏洞”吗?是的。。。对于大小为N的文件,OP使用O(N^2)
空格。并分配O(N^3)
空间!
private static final BiPredicate<Path, BasicFileAttributes> DOCX_FILES
= (path, attrs) -> attrs.isRegularFile
&& path.getFileName().toString().endsWith(".docx");
final Path basePath = Paths.get("C:\\Users\\localness\\Desktop\\Locker");
try (
final Stream<Path> stream = Files.find(basePath, Integer.MAX_VALUE, DOCX_FILES);
) {
stream.forEach(path -> whatever)
}
final URI uri = URI.create("jar:" + docxPath.toUri());
try (
final FileSystem zipfs = FileSystems.newFileSystem(uri, Collections.emptyMap());
final Reader reader = Files.newBufferedReader(zipfs.getPath("word/document.xml"),
StandardCharsets.UTF_8);
) {
// use the reader
} catch (FileNotFoundException ignored) {
// no such file in zip
}