我正在读取一个有900万行的CSV文件,我需要将每行转换为一个对象,并将其存储在列表或缓冲区中,以便稍后写入随机访问文件。
当我尝试将投资者对象添加到列表中时,当它达到6,462547万行时,它会给出以下错误:Java堆空间
如何解决这个错误?我如何用一些Buffer方法替换List ?
链接到我正在阅读的文件
我的阅读函数(注意:TextFile类可以被BufferedReader取代):
public List<Object> lerDadosCSV(String arquivoCSV, JProgressBar progressBar, JTextField textField, int tipo) {
long indice = 0;
numeroTotalLinhas = numeroTotalLinhas(arquivoCSV) * 2;
try (TextFile textFile = new TextFile(arquivoCSV)) {
DecimalFormat decimalFormat = new DecimalFormat("#,###");
String linha;
List<Object> records = new ArrayList<>();
while ((linha = textFile.readLine()) != null) {
if (indice != 0) {
records.add(tipo == 0 ? montaEstoque(linha.split(";")) : montaInvestidor(linha.split(";")));
}
textField.setText(decimalFormat.format(indice));
progressBar.setValue((int) (indice * 100 / numeroTotalLinhas));
progressBar.setString((int) (indice * 100 / numeroTotalLinhas) + "%");
indice++;
}
return records;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
函数montaInvestidor:
public static Investidor montaInvestidor(String[] splitLinha) {
try {
boolean operou = (splitLinha[10].contains("s|S")) ? true : false,
situacao = (splitLinha[9].contains("a|A")) ? true : false;
Investidor investidor = new Investidor(Integer.parseInt(splitLinha[0]), formataData.parse(splitLinha[1]),
splitLinha[2].trim(), splitLinha[3].trim(), splitLinha[4].trim(), splitLinha[6].trim(),
splitLinha[7].trim(), splitLinha[8].trim(), Integer.parseInt(splitLinha[5]), situacao, operou);
return investidor;
} catch (NumberFormatException | ParseException e) {
e.printStackTrace();
return null;
}
}
长话短说…堆总是有限的,每个平台都有一个最大值。在Windows系统中,大约是2GB。所以默认值非常小。
如何绕过它?
-Xmx
设置分配给这个特定程序的最大堆空间。这通常是不推荐的,但当你必须使用内存时,我个人认为这是可以的。
所以你可以在你的jar
或你的IDE中使用它,把它添加到VM参数中。
一个例子是:
java -jar -Xmx4g myJar.jar
4g = 4GB
或者你可以用mb
等等