2015-11-13 103 views
3

我不知道为什么我得到这个错误。我找不到任何方法来保存更多的内存。如果有人可以帮助我使这更有效率,它将不胜感激。 有人也可以检查我的代码,看看我是否做了什么傻事?提前致谢。java.lang.OutOfMemoryError:Java堆空间没有更多空间

主类

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) 
+0

为什么你使用'File'?另外,您可以使用zip文件系统提供程序 – fge

+0

您如何执行此代码?如果它在IDE中运行,请尝试给出更多的堆空间 – Valijon

+0

这是一个“泄漏”? – m0skit0

回答

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)

,或者更好的办法是使用一个StringBuffer和你读追加到它。

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

对于一个大小为N的文件,OP使用'O(N^2)'空间。并分配'O(N^3)'空间! –

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) 
} 

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

现在,它看起来像你想要做的是打开docx文件作为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 
} 
相关问题