OutOfMemoryError: Java пространство кучи при попытке создать ArrayList - PullRequest
0 голосов
/ 02 марта 2020

Я пытаюсь написать программу, которая преобразует все строки G1 кода G в строки, которые говорят: MOVX (x-coordinate of G1 command)

Например. G1 X0.1851 должно стать MOVX(0.1851)

В данный момент программа просто добавляет прочитанный текстовый файл и печатает новый код ниже старого в том же текстовом файле.

Проблема в том, что когда я пытаюсь создать список массива числа после X в G-Code, у меня возникает проблема с переполнением памяти в пространстве кучи.

Я добавил clear() оператор после каждой итерации строки G-Code, чтобы попытаться предотвратить увеличение и увеличение списка массивов, но он продолжает переполняться.

Вот мой код:

package textfiles;
import java.io.IOException;
import java.util.ArrayList;


public class FileData {

    public static void main(String[] args) throws IOException {

        String file_name = "C:/blabla";

        try {
            ReadFile file = new ReadFile(file_name);
            WriteFile data = new WriteFile(file_name, true);
            String[] aryLines = file.OpenFile();

            int i;
            int j;
            int y;

            for (i=0; i < aryLines.length; i++ ) { //goes through whole text file
                System.out.println( aryLines[ i ]);

                if (i == 0) {
                    data.writeToFile("");
                    System.lineSeparator();
                }

                char[] ch = aryLines[ i ].toCharArray();
                ArrayList<Character> num = new ArrayList<Character>();
                String xCo = null;


                boolean counterX = false;

                if ((ch[0]) == 'G' && ch[1] == '1') {

                    for (j = 0; j < ch.length; j++) { //goes through each line of text file

                        for (y = 0; counterX == true; y++) {
                            num.add(ch[j]);
                        }

                        if (ch[j] == 'X') {
                            counterX = true;
                        }

                        else if (ch[j] == ' ') {
                            counterX = false;
                        }
                    }
                    xCo = num.toString();
                    data.writeToFile("MOVX (" + xCo + ")");
                }
                num.clear();
            }
        }
        catch (IOException e) {
            System.out.println( e.getMessage() );
        }

        System.out.println("Text File Written To");

    }
}

1 Ответ

0 голосов
/ 02 марта 2020

Я бы посоветовал избегать чтения данных в память и использовать вместо этого потоковую передачу. Тогда функция, которая преобразует строки, может выглядеть так:

    public void convertFile(String fileName, String tmpFileName) throws IOException {
        try (FileWriter writer = new FileWriter(tmpFileName, true)){
            Pattern pG1_X = Pattern.compile("^G1 X");
            Files.newBufferedReader(Paths.get(fileName)).lines().forEach(line -> {
                try {
                    double x = Double.parseDouble(pG1_X.split(line)[1]); // get coordinate
                    String newLine = String.format("MOVX(%f)\n",x);      // attempt to replace coordinate format
                    writer.write(newLine);
                } catch (Exception e) {
                    LOGGER.log(Level.WARNING, String.format("error wile converting line %s", line), e);
                }
            });
        }
    }

Тестовый пример, который демонстрирует, как это работает:

package com.github.vtitov.test;

import org.junit.experimental.theories.DataPoints;
import org.junit.experimental.theories.Theories;
import org.junit.experimental.theories.Theory;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Random;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;

import java.nio.file.StandardCopyOption;

@RunWith(Theories.class)
public class ReadWriteTest {
    final static Logger LOGGER = Logger.getLogger(ReadWriteTest.class.getName());

    public void convertFile(String fileName, String tmpFileName) throws IOException {
        try (FileWriter writer = new FileWriter(tmpFileName, true)){
            Pattern pG1_X = Pattern.compile("^G1 X");
            Files.newBufferedReader(Paths.get(fileName)).lines().forEach(line -> {
                try {
                    double x = Double.parseDouble(pG1_X.split(line)[1]); // get coordinate
                    String newLine = String.format("MOVX(%f)\n",x);      // attempt to replace coordinate format
                    writer.write(newLine);
                } catch (Exception e) {
                    LOGGER.log(Level.WARNING, String.format("error wile converting line %s", line), e);
                }
            });
        }
    }


    @DataPoints static public Long[] fileSizes() {return new Long[]{100L,10_000L,1_000_000L}; }
    @Theory
    public void readWriteTest(Long fileSize) throws Exception {
        TemporaryFolder folder = TemporaryFolder.builder().parentFolder(new File("target")).build();
        folder.create();
        File file = folder.newFile(UUID.randomUUID() + ".txt");
        File tmpFile = folder.newFile(file.getName() + ".tmp");
        createFile(fileSize, file);
        String filePath = file.getPath();
        LOGGER.info(String.format("created file %s of %d lines", filePath, fileSize));
        String tmpFilePath = filePath + ".tmp";
        convertFile(filePath, tmpFilePath);
        LOGGER.info(String.format("file %s converted to %s", filePath, tmpFilePath));
        //assert false;
        Files.move(new File(tmpFilePath).toPath(), new File(filePath).toPath(),
                StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE);
        LOGGER.info(String.format("file %s moved to %s", tmpFilePath, filePath));
        folder.delete();
    }

    private void createFile(long fileSize, File file) throws Exception {
        try (FileWriter writer = new FileWriter(file,true)) {
            Random rnd = new Random();
            rnd.doubles(fileSize).forEach(l -> {
                try { writer.write(String.format("G1 X%f\n", l)); } catch (IOException ignored) {}
            });
        }
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...