【发布时间】:2020-02-02 09:56:38
【问题描述】:
我正在尝试运行下面的程序,但在 StringBuilder 附加循环结构期间出现 OutOfMemory 错误。
- 我正在尝试做任何事情来降低内存使用量,使其能够读取 CSV 文件(超过 200,000 行但只有 3 列:项目、评级、用户)。
- 然后我将创建一个 2D int 数组,其中唯一项表示 行,唯一用户代表列,交集是 评分。
- 最后,我将使用 StringBuilder 来帮助创建输出 CSV 文件
感谢您的帮助和时间。
List<String> userList = new ArrayList<String>();
List<String> itemList = new ArrayList<String>();
FileInputStream stream = null;
Scanner scanner = null;
int[][] layout = new int[10672][24303];
int indexItemList = 0;
double temp = 0;
try{
stream = new FileInputStream(fileName);
scanner = new Scanner(stream, "UTF-8");
while (scanner.hasNextLine()){
String line = scanner.nextLine();
if (!line.equals("")){
String[] elems = line.split(",");
if (indexItemList == 0) {
temp = Double.valueOf(elems[1]);
layout[0][0] = (int)temp;
itemList.add(elems[0]);
userList.add(elems[2]);
indexItemList++;
}
else {
boolean itemFound = itemList.contains(elems[0]);
boolean userFound = userList.contains(elems[2]);
int indexItem = 1;
int indexUser = 1;
if ((itemFound) && (userFound)) {
indexItem = itemList.indexOf(elems[0]);
indexUser = userList.indexOf(elems[2]);
temp = Double.valueOf(elems[1]);
layout[indexItem][indexUser] = (int)temp;
}
else if ((itemFound) && (!userFound)) {
userList.add(elems[2]);
indexItem = itemList.indexOf(elems[0]);
indexUser = userList.indexOf(elems[2]);
temp = Double.valueOf(elems[1]);
layout[indexItem][indexUser] = (int)temp;
}
else if ((!itemFound) && (userFound)){
itemList.clear();
itemList.add(elems[0]);
indexUser = userList.indexOf(elems[2]);
temp = Double.valueOf(elems[1]);
layout[indexItemList][indexUser] = (int)temp;
indexItemList++;
}
else if (!((itemFound) && (userFound))) {
itemList.clear();
itemList.add(elems[0]);
userList.add(elems[2]);
indexUser = userList.indexOf(elems[2]);
temp = Double.valueOf(elems[1]);
layout[indexItem][indexUser] = (int)temp;
indexItemList++;
}
}
}
}
if (scanner.ioException() != null){
throw scanner.ioException();
}
}
catch (IOException e){
System.out.println(e);
}
finally{
try{
if (stream != null){
stream.close();
}
}
catch (IOException e){
System.out.println(e);
}
if (scanner != null){
scanner.close();
}
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < layout.length; i++){
for (int j = 0; j < layout[i].length; j++){
sb.append(layout[i][j] + "");
layout[i][j] = 0;
if (j < layout[i].length - 1){
sb.append(",");
}
}
sb.append("\n");
}
【问题讨论】:
-
我觉得你不需要
StringBuilder:你可以直接写入输出文件。 -
您需要的最终 CSV 是什么?您是否尝试为每个独特的用户/项目组合写出一个值?要减少字符串生成器的内存占用,请频繁写入文件,而不是尝试将整个 csv 保存在内存中。
标签: java csv memory-management out-of-memory heap-memory