Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
string.split中的Java outOfMemory异常_Java_String_Exception - Fatal编程技术网

string.split中的Java outOfMemory异常

string.split中的Java outOfMemory异常,java,string,exception,Java,String,Exception,我有一个很大的txt文件,里面有整数。文件中的每一行都有两个用空格分隔的整数。文件大小为63MB Pattern p = Pattern.compile("\\s"); try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) { String line; while ((line = reader.readLine()) != null) {

我有一个很大的txt文件,里面有整数。文件中的每一行都有两个用空格分隔的整数。文件大小为63MB

Pattern p = Pattern.compile("\\s");
    try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
        String line;
        while ((line = reader.readLine()) != null) {
            String[] tokens = p.split(line);
            String s1 = new String(tokens[0]);
            String s2 = new String(tokens[1]);
            int startLabel = Integer.valueOf(s1) - 1;
            int endLabel = Integer.valueOf(s2) - 1;
            Vertex fromV = vertices.get(startLabel);
            Vertex toV = vertices.get(endLabel);
            Edge edge = new Edge(fromV, toV);
            fromV.addEdge(edge);
            toV.addEdge(edge);
            edges.add(edge);
            System.out.println("Edge from " + fromV.getLabel() + " to " + toV.getLabel());
        }

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

线程“main”java.lang.OutOfMemoryError中的异常:java堆空间 位于java.util.Arrays.copyOfRange(Arrays.java:2694) 位于java.lang.String。(String.java:203) 位于java.lang.String.substring(String.java:1913) 在java.lang.String.subSequence(String.java:1946) 位于java.util.regex.Pattern.split(Pattern.java:1202) 位于java.util.regex.Pattern.split(Pattern.java:1259) 在SCC.main(SCC.java:25) 为什么我会得到这个例外?如何更改代码以避免它

编辑: 我已经将堆大小增加到2048m。 什么在消费它?这也是我想知道的

据我所知,jvm应该为顶点列表、边集、缓冲读取器的缓冲区和一个小字符串“line”分配内存。我不知道这是从哪里来的


我读过string.split()方法。我认为这会导致内存泄漏,但我不知道该怎么办。

最简单的方法:增加堆大小:
向jvm添加-Xmx512m-Xms512m(甚至更多)参数最简单的方法:增加堆大小:
向jvm添加-Xmx512m-Xms512m(甚至更多)参数,使用
-Xmx
jvm选项增加堆内存限制


更多信息。

使用
-Xmx
JVM选项增加堆内存限制


更多信息。

您有异常,因为您的堆空间已完成。尝试使用

 java -Xms512 -Xmx2048 (for example)

您有异常,因为您的堆空间已完成。尝试使用

 java -Xms512 -Xmx2048 (for example)

您首先应该尝试的是将文件减小到足以工作的大小。这将允许你评估你的问题有多大

其次,您的问题肯定与
String#split
无关,因为您一次只在一行上使用它。消耗堆的是
顶点
实例。您将不得不重新设计它,使其占用更小的空间,或者彻底修改您的算法,以便只处理内存中图形的一部分,其余部分在磁盘上

附言:只是一个一般的Java注释:不要写

String s1 = new String(tokens[0]);
String s2 = new String(tokens[1]);
你只需要

String s1 = tokens[0];
String s2 = tokens[1];

或者甚至直接使用
标记[0]
而不是
s1
,因为它同样清晰。

您首先应该尝试的是将文件减小到足以工作的大小。这将允许你评估你的问题有多大

其次,您的问题肯定与
String#split
无关,因为您一次只在一行上使用它。消耗堆的是
顶点
实例。您将不得不重新设计它,使其占用更小的空间,或者彻底修改您的算法,以便只处理内存中图形的一部分,其余部分在磁盘上

附言:只是一个一般的Java注释:不要写

String s1 = new String(tokens[0]);
String s2 = new String(tokens[1]);
你只需要

String s1 = tokens[0];
String s2 = tokens[1];

或者甚至直接使用
标记[0]
而不是
s1
,因为它同样清晰。

当您在尝试解析内容时获得OOM时,只是您使用的方法不可伸缩。尽管增加堆可能暂时解决这个问题,但它是不可伸缩的。例如,如果明天您的文件大小增加一个数量级或数量级,您将回到原点。 我建议尝试将文件分块读取,缓存文件的x行,读取它,清除缓存,然后重新执行该过程。
您可以使用ehcache或guava cache。

当您在尝试解析内容时获得OOM时,只是您使用的方法不可伸缩。尽管增加堆可能暂时解决这个问题,但它是不可伸缩的。例如,如果明天您的文件大小增加一个数量级或数量级,您将回到原点。 我建议尝试将文件分块读取,缓存文件的x行,读取它,清除缓存,然后重新执行该过程。
您可以使用ehcache或guava cache。

由于您的程序在java堆中存储了太多数据,因此出现了此异常

尽管Pattern.split()方法中显示了异常,但真正的罪魁祸首可能是代码中的任何大内存用户,例如您正在构建的图形。查看您提供的内容,我怀疑graph数据结构存储了大量冗余数据。您可能需要研究一种更节省空间的图形结构

如果您使用的是Sun JVM,请尝试JVM选项-XX:+HeapDumpOnOutOfMemoryError来创建一个堆转储,并对任何内存过大的用户进行分析,然后使用该分析来优化代码。有关更多信息,请参阅


如果像其他人指出的那样,这对您来说太多了,请尝试增加JVM堆空间,使您的程序不再崩溃。

您会遇到此异常,因为您的程序在java堆中存储了太多数据

尽管Pattern.split()方法中显示了异常,但真正的罪魁祸首可能是代码中的任何大内存用户,例如您正在构建的图形。查看您提供的内容,我怀疑graph数据结构存储了大量冗余数据。您可能需要研究一种更节省空间的图形结构

如果您使用的是Sun JVM,请尝试JVM选项-XX:+HeapDumpOnOutOfMemoryError来创建一个堆转储,并对任何内存过大的用户进行分析,然后使用该分析来优化代码。有关更多信息,请参阅


如果像其他人指出的那样,这对您来说太多了,请尝试增加JVM堆空间,使您的程序不再崩溃。

您解析字符串的方式可能会改变

try (Scanner scanner = new Scanner(new FileReader(filePath))) {
    while (scanner.hasNextInt()) {
        int startLabel = scanner.nextInt();
        int endLabel = scanner.nextInt();
        scanner.nextLine(); // discard the rest of the line.
        // use start and end.

    }

我怀疑内存消耗实际上是在您构建的数据结构中,而不是在您读取数据的方式中,但这应该会使它更加明显。

您解析字符串的方式可能会改变

try (Scanner scanner = new Scanner(new FileReader(filePath))) {
    while (scanner.hasNextInt()) {
        int startLabel = scanner.nextInt();
        int endLabel = scanner.nextInt();
        scanner.nextLine(); // discard the rest of the line.
        // use start and end.

    }
我怀疑