错误内存VM java,java.lang.OutOfMemoryError:Java堆空间

时间:2014-09-06 17:39:58

标签: java performance jvm

朋友我需要你的帮助,我必须处理一个包含大量信息的大文件(关于文件的重量为30 Mb)。处理此信息文件时,java给出了这个错误:


Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Arrays.java:2367)
    at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:130)
    at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:114)
    at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:535)
    at java.lang.StringBuffer.append(StringBuffer.java:322)
    at java.io.StringWriter.write(StringWriter.java:94)
    at java.io.Writer.write(Writer.java:127)
    at com.sun.org.apache.xml.internal.serialize.Printer.printText(Printer.java:170)
    .....

我的代码是:


...

    public Document generateXML(File file, String type) {
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder docBuilder = dbf.newDocumentBuilder();

            Document document = docBuilder.newDocument();
            Element rootElement = document.createElement("data");
            document.appendChild(rootElement);

            Element informacionElement = document.createElement("information");
            rootElement.appendChild(informacionElement);

            Element entityElement = document.createElement("entity");
            entityElement.appendChild(document.createTextNode("ANYTHING"));
            informacionElement.appendChild(entityElement);

            Element entityCode = document.createElement("code");
            entityCode.appendChild(document.createTextNode(0000));
            informacionElement.appendChild(entityCode);

            Element fileElement = document.createElement("FILENAME");
            fileElement.appendChild(document.createTextNode(file.getName()));
            informacionElement.appendChild(fileElement);

            Element detailElement = document.createElement("detail");
            rootElement.appendChild(detailElement);

            Path path = Paths.get(file.getAbsolutePath());
            Scanner tmpFile = new Scanner(path, StandardCharsets.UTF_8.name());

            String[] tmpTags = keyXml.get(type);
            int row = 1;

            while (tmpFile.hasNextLine()) {

                Element rowElement = document.createElement("row");
                filaElement.setAttribute("id", Integer.toString(row));

                Scanner tmpLine = new Scanner(tmpFile.nextLine());
                tmpLine.useDelimiter("\\|");
                int index = 0;
                while (tmpLine.hasNext()) {
                    Element element = document.createElement(tmpTags[index]);
                    String text = tmpLine.next().trim();
                    element.appendChild(document.createTextNode(text));
                    filaElement.appendChild(element);
                    ++index;
                }
                detailElement.appendChild(filaElement);
                ++fila;
            }
            return document;
        } catch (ParserConfigurationException | IOException ex) {
            Logger.getLogger(HandlerXML.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }
...

此代码生成以下XML文档:

    <data>
        <information>
            <entity>ANYTHING</entity>
            <code>0000</code>
            <filename>filename_XXX</filename>
        </information>
        <detail>
            <row id="1">
                <tag1>0099</tag1>
                <tag2>2014</tag2>
                <tag3>05</tag3>
                <tag4>0015</tag4>
                <tag5>06</tag5>
                <tag6>06</tag6>
                <tag7>000000000099907</tag7>
                <tag8>098026</tag8>
                <tag9>00000781.40</tag9>
                <tag10>E</tag10>
                <tag11>000000006804750</tag11>
                <tag12>xxx</tag12>
                <tag13>xxxx</tag13>
                <tag14>xxx</tag14>
                <tag15></tag15>
                <tag16></tag16>
                <tag17>xx</tag17>
                <tag18>xxx</tag18>
                <tag19>1014</tag19>
                <tag20>05</tag20>
                <tag21>11111</tag21>
                <tag22>1014</tag22>
                <tag23>00000000000000000000</tag23>
                <tag24>3</tag24>
                <tag25>20101</tag25>
                <tag26>00000000</tag26>
                <tag27>46671</tag27>
                <tag28>1</tag28>
                <tag29>N</tag29>
                <tag30></tag30>
                <tag31></tag31>
                <tag32>A</tag32>
                <tag33></tag33>
                <tag34></tag34>
                <tag35></tag35>
                <tag36></tag36>
                <tag37></tag37>
                <tag38></tag38>
            </row>
            ............   
        </detail>
    </data>

获取xml数据的词是:

** 0099 | 2014 | 05 | 0015 | 06 | 06 | 00000000003101 | 066671 | 000077777.00 | E | 000000002719415 | xxx | xxxxxx | xxxxxxxx | | | xxxxxx | | 1014 | 05 | 12254758 | 1014 | 00000000000000000000 | 3 | 20101 | 00000000 | 748596 | 1 | X | | | Q | | | | | **

现在假设必须为100000行信息​​生成xml,如果您想知道,必须将所有行转换为XML格式。

问题是,当你将对象转换为 STRING DOCUMENT 时,我得到了我之前显示的错误,我用来转换 DOCUMENT的函数 STRING 是:

    private static String convertDocumentToString(Document doc) {
        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer transformer;
        try {
            transformer = tf.newTransformer();
            StringWriter writer = new StringWriter();
            transformer.transform(new DOMSource(doc), new StreamResult(writer));
            return writer.getBuffer().toString();
        } 
        catch (TransformerException e) {}
        return "";
    }

现在这个错误是虚拟内存,java VM的解决方法是用 -Xmx #### m 来增加内存,但是我想知道这是否通过其他方式解决了,试着处理数据type with:String,StringBuilder和byte。有谁能解决这个问题?

提前致谢。

3 个答案:

答案 0 :(得分:2)

&#34; 30 MB&#34;并不是那么大。

建议:将其添加到Java命令行:-XX:MaxPermSize=512m

ALSO:

&#39;希望有所帮助!

答案 1 :(得分:1)

&#34;一个非常大的文件&#34;并不表示您的程序将使用大量内存。它更可能意味着您可能花费相当多的时间来处理文件,但实际上与您使用的空间无关。

只有文件的当前相关部分应保留在内存中。

答案 2 :(得分:1)

  

但是quies知道这是否通过其他方式解决了

是的,当然还有另一种方法:在序列化XML时,不要使用StringWriter作为目标。如果您希望XML最终存储在文件中,请为其创建适当的FileWriter,并将其交给您的XML序列化代码。

如果您从异常的堆栈跟踪中包含更多内容,我可能能够为您提供比上述更精确的建议。产生异常的实际代码也会有所帮助。