Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/330.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
如何删除Java OutOfMemoryError_Java_Out Of Memory - Fatal编程技术网

如何删除Java OutOfMemoryError

如何删除Java OutOfMemoryError,java,out-of-memory,Java,Out Of Memory,我有一个程序,它获取了一个非常大的txt数据,并改变了这个txt数据中某些列的顺序。有关它的具体功能的更多详细信息,请参见我的问题。我使用带有映射的列表,我可以想象这对于java虚拟机来说太多了,因为txt文件有400000个条目,但我不知道还能做什么。我用一个较小的txt文件试过,然后效果很好。否则它会运行一个多小时,然后我会得到一个OutOfMemory错误 这是我的密码: import java.io.BufferedReader; import java.io.File; import

我有一个程序,它获取了一个非常大的txt数据,并改变了这个txt数据中某些列的顺序。有关它的具体功能的更多详细信息,请参见我的问题。我使用带有映射的列表,我可以想象这对于java虚拟机来说太多了,因为txt文件有400000个条目,但我不知道还能做什么。我用一个较小的txt文件试过,然后效果很好。否则它会运行一个多小时,然后我会得到一个OutOfMemory错误

这是我的密码:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

public class Final {

public static void main(String[] args) {

    String path = "C:\\\\\\\\Users\\\\\\\\Ferid\\\\\\\\Downloads\\\\\\\\secdef\\\\\\\\secdef.txt";

    File file = new File(path);

    new Final().updateFile(file);
}

private void updateFile(File file) {

    List<String> allRows = getAllRows(file);

    String[] baseRow = allRows.get(0).split("\\|");

    List<String> columns = getBaseColumns(baseRow);
    System.out.println(columns.size());

    appendNewColumns(allRows, columns);
    System.out.println(columns.size());

    List<Map<String, String>> mapList = convertToMap(allRows, columns);

    List<String> newList = new ArrayList<String>();

    appendHeader(columns, newList);

    appendData(mapList, newList, columns);

    String toPath = "C:\\\\\\\\Users\\\\\\\\Ferid\\\\\\\\Downloads\\\\\\\\secdef\\\\\\\\finalz2.txt";

    writeToNewFile(newList, toPath);

}

/**
 * Gibt alle Zeilen aus der Datei zurück.
 */
private static List<String> getAllRows(File file) {

    List<String> allRows = new ArrayList<>();
    BufferedReader reader = null;
    try {
        reader = new BufferedReader(new FileReader(file));
        String row = null;
        int i = 0;
        while ((row = reader.readLine()) != null) {
            allRows.add(row);

        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    return allRows;
}

/**
 * Gibt die Hauptspalten aus der 1. Zeile zurück.
 */
private static List<String> getBaseColumns(String[] baseRow) {
    List<String> columns = new ArrayList<>();
    for (String rowEntry : baseRow) {
        String[] entry = rowEntry.split("=");
        columns.add(entry[0]);
    }
    return columns;
}

/**
 * Fügt alle neuen Spalten hinzu.
 */
private static void appendNewColumns(List<String> rows, List<String> columns) {
    for (String row : rows) {
        String[] splittedRow = row.split("\\|");
        for (String column : splittedRow) {
            String[] entry = column.split("=");
            if (columns.contains(entry[0])) {
                continue;
            }
            columns.add(entry[0]);
        }
    }
}

/**
 * Konvertiert die Listeneinträge zu Maps.
 */
private static List<Map<String, String>> convertToMap(List<String> rows, List<String> columns) {
    List<Map<String, String>> mapList = new ArrayList<>();
    for (String row : rows) {
        Map<String, String> map = new TreeMap<>();
        String[] splittedRow = row.split("\\|");
        List<String> rowList = Arrays.asList(splittedRow);
        for (String col : columns) {
            String newCol = findByColumn(rowList, col);
            if (newCol == null) {
                map.put(col, "null");
            } else {
                String[] arr = newCol.split("=");
                map.put(col, arr[1]);
            }
        }
        mapList.add(map);
    }
    return mapList;

}

/**
 * 
 */
private static String findByColumn(List<String> row, String col) {
    return row.stream().filter(o -> o.startsWith(col)).findFirst().orElse(null);
}

/**
 * Fügt die Header-Zeile in die neue Liste hinzu.
 */
private static void appendHeader(List<String> columns, List<String> list1) {
    String header = "";
    for (String column : columns) {
        header += column + "|";
    }
    list1.add(header + "\n");
}

/**
 * Fügt alle Daten in die entsprechenden neuen Dateien hinzu.
 */
private static void appendData(List<Map<String, String>> mapList, List<String> list1, List<String> columns) {
    for (Map<String, String> entry : mapList) {
        String line = "";
        for (String key : columns) {
            // for (String key : entry.keySet()) {
            line += entry.get(key) + "|";
        }

        list1.add(line + "\n");
    }
}

/**
 * Schreibt alle Werte in die neue Datei.
 */
private static void writeToNewFile(List<String> list, String path) {
    FileOutputStream out = null;
    try {
        out = new FileOutputStream(new File(path));
        for (String line : list) {
            out.write(line.getBytes());
        }
        out.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

}

您可以通过指定:-Xmx指定JVM可以使用的最大内存

例如-Xmx8G,
使用M或G

我们实际上无法给出分配内存量的具体建议,因为这在很大程度上取决于您的服务器设置、用户群的大小以及他们的行为。您需要找到一个适合您的值,即没有明显的GC暂停,也没有OutOfMemory错误

作为参考,用于更改内存堆分配的3个最常见参数为:

Xms—堆的最小大小 Xmx-堆的最大大小 XX:MaxPermSize-PermGen的最大大小这在Java 8及更高版本中未使用 如果您确实决定增加内存设置,则需要遵循一些一般准则

以小的增量增加Xmx,例如每次512mb,直到 经历OutOfMemory错误的时间越长。这是因为 堆超出了服务器的能力,因此无法充分回收垃圾 收集可能会导致其他问题,例如性能/冻结 如果您的错误是java。朗。OutOfMemoryError:永久空间, 以256mb的增量增加-XX:MaxPermSize参数,直到 错误停止发生。 如果您的错误未引用PermGen,则无需 增加它。简单地说,PermGen用于存储 类,并且在大小上通常是静态的,并且已被删除 在Java8中。更多信息请点击这里。考虑将XMS和XMX设置为相同 值,因为这可以减少GC发生所需的时间 不要尝试在每个集合上调整堆的大小。 如果在Windows上启动Confluence作为服务,则不应使用这些说明。请参阅下面的Windows服务部分

只有在通过批处理文件启动Confluence时,才应遵循这些说明。当Confluence作为服务启动时,不使用批处理文件

要在Windows安装中从.bat文件启动时配置系统属性

停堆汇流 从/bin单机版或/bin EAR-WAR安装,打开setenv.bat。 找到该部分 CATALINA_OPTS=-Xms1024m-Xmx1024m-XX:+UseG1GC$CATALINA_OPTS在汇流5.8或以上

CATALINA_OPTS=$CATALINA_OPTS-Xms1024m-Xmx1024m-XX:MaxPermSize=256m-XX:+UseG1GC在汇流5.6或5.7中

在以前的版本中,JAVA_OPTS=-Xms256m-Xmx512m-XX:MaxPermSize=256m

Xmx是最大值,Xms是最小值,MaxPermSize是PermGen。 起始汇流
在这种情况下,如果可能的话,可以逐行读取文件并分别处理每一行,而不是将整个文件保存在内存中

当前,您的代码如下所示:

  BufferedReader reader = null;
  BufferedWriter writer = null;
    try {
        reader = new BufferedReader(new FileReader(file));
        String row = null;
        int i = 0;
        List<String> columns = new ArrayList<>();
        while ((row = reader.readLine()) != null) {
            columns.addAll(getColumns(row));

        }

        reader = new BufferedReader(new FileReader(file));
        writer = new BufferedWriter(new FileWriter(outFile));
        int i = 0;
        while ((row = reader.readLine()) != null) {
            writeRow(row, columns, writer);

        }
    } catch (IOException e) {
        e.printStackTrace();
    }
将所有行读入列表L 对于L中的每一行,查找所有列 在映射中使用空字符串将L中的行转换为映射,而不是不设置值!!这可能是最终真正让你心痛的原因! 将映射序列化为行 我只需要增加可用内存就可以调用bs,然后它稍后就会失败。您在内存使用和性能方面存在一般性问题。让我提出另一种方式:

 1. for each line read (don't read the whole file at once!):
    1.1 find columns, collect in List C
 2. for each line read (again, don't read the whole file at once, do it as you read):
    2.2 for each column in C, write value if the row contains it, or null
    2.3 append to the result file (also don't keep the result in memory!)
有点像这样:

  BufferedReader reader = null;
  BufferedWriter writer = null;
    try {
        reader = new BufferedReader(new FileReader(file));
        String row = null;
        int i = 0;
        List<String> columns = new ArrayList<>();
        while ((row = reader.readLine()) != null) {
            columns.addAll(getColumns(row));

        }

        reader = new BufferedReader(new FileReader(file));
        writer = new BufferedWriter(new FileWriter(outFile));
        int i = 0;
        while ((row = reader.readLine()) != null) {
            writeRow(row, columns, writer);

        }
    } catch (IOException e) {
        e.printStackTrace();
    }

你给Java分配了多少内存?@JFMeier在哪里可以看到这个?