java.lang.OutOfMemoryError:Java堆空间没有更多空间

时间:2015-11-13 22:17:49

标签: java out-of-memory

我不清楚为什么会收到此错误。我找不到任何方法来节省更多的内存。如果有人能帮助我提高效率,我们将不胜感激。 有人也可以查看我的代码,看看我做了什么傻事吗?提前谢谢。

MAIN CLASS

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(">", "&gt;");
                        texttag = texttag.replace("<", "&lt;");
                        // 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;
        }
    }
}

错误讯息:

Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Unknown Source)
    at java.lang.AbstractStringBuilder.expandCapacity(Unknown Source)
    at java.lang.AbstractStringBuilder.ensureCapacityInternal(Unknown Source)
    at java.lang.AbstractStringBuilder.append(Unknown Source)
    at java.lang.StringBuilder.append(Unknown Source)
    at DocxCompair.extractFile(DocxCompair.java:26)
    at DocxCompair.Readfile(DocxCompair.java:58)
    at Main.lambda$0(Main.java:37)
    at Main$$Lambda$17/772250001.accept(Unknown Source)
    at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(Unknown Source)
    at java.util.stream.ReferencePipeline$3$1.accept(Unknown Source)
    at java.util.Iterator.forEachRemaining(Unknown Source)
    at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Unknown Source)
    at java.util.stream.AbstractPipeline.copyInto(Unknown Source)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
    at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(Unknown Source)
    at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(Unknown Source)
    at java.util.stream.AbstractPipeline.evaluate(Unknown Source)
    at java.util.stream.ReferencePipeline.forEach(Unknown Source)
    at Main.filelistandfind(Main.java:32)
    at Main$2.mouseClicked(Main.java:106)
    at java.awt.AWTEventMulticaster.mouseClicked(Unknown Source)
    at java.awt.Component.processMouseEvent(Unknown Source)
    at javax.swing.JComponent.processMouseEvent(Unknown Source)
    at java.awt.Component.processEvent(Unknown Source)
    at java.awt.Container.processEvent(Unknown Source)
    at java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)

2 个答案:

答案 0 :(得分:4)

你正在建造一个巨大的巨型弦。看看你的代码:

        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文件的 (10次读取200k)你的结果实际上超过了204mb。

原因是因为你在做result += result + new String(buffer); 你应该做result += new String(buffer)

OR,最好是使用StringBuffer并在阅读时附加到它。

StringBuffer result = new StringBuffer();
len = 0;
while ((len = zipIn.read(buffer)) > 0 ) {
    result.append( new String(buffer));
}

答案 1 :(得分:0)

首先,你不能完全关闭所有资源。

其次,你可以尝试几件事。

首先,您可以使用名为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)
}

请注意,我在这里关闭了流。

现在,您想要做的就是将zipx文件作为zip打开,并阅读名为word/document.xml的条目的内容。再次使用JSR 203:

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
}