尝试在内存中创建大型 zip 文件时出现内存分配错误
Memory allocation error when trying to create a large zip file in memory
内存分配错误似乎特别发生在遇到 for 循环时,并且仅适用于非常大的 storesList。如果 storesList.size() 约为 200 万,我只能遇到内存分配错误。我粘贴了 for 循环的片段,它应该根据循环中的每个对象创建一个新行。
该函数接受一个 ZipOutputStream 和一个对象列表。
public ZipOutPutStream setStream(ZipoutputStream zos, List<Stores> storesList){
zos.setLevel(1);
newRow = new StringBuilder();
for (Stores s: storesList) {
//clearing the stringbuilder each iteration
newRow.setLength(0);
newRow.append(s.getId());
newRow.append(",")
.append(s.getTitle()).append(s.getDescription());
newRow.append("\n");
}
byte[] data = result.toString().getBytes();
zos.write(data, 0, data.length);
zos.closeEntry();
zos.close();
return zos;
}
我应该改变什么才能处理非常大的列表?
当您可以直接传输相同的数据时,不要构建内存结构 - 因为巨大的结构可能会在 toString()
或 getBytes()
调用时命中 OutOfMemoryError
。
如果您正在处理平台行分隔符,您可以这样写行:
PrintWriter w = new PrintWriter(zos/*,false, orCharSetHere*/);
for (Stores s : storesList) {
w.println(s.getId() + "," + s.getTitle() + s.getDescription());
}
w.flush();
但是如果您想要所有平台的 \n
行分隔符,可以使用以下方式发送行:
OutputStreamWriter w = new OutputStreamWriter(zos/*, orCharSetHere*/);
for (Stores s : storesList) {
w.write(s.getId() + "," + s.getTitle() + s.getDescription()+"\n");
}
w.flush();
必须刷新写入程序以确保在关闭 zip 条目或流之前将任何缓冲数据写入 ZipOutputStream
。
内存分配错误似乎特别发生在遇到 for 循环时,并且仅适用于非常大的 storesList。如果 storesList.size() 约为 200 万,我只能遇到内存分配错误。我粘贴了 for 循环的片段,它应该根据循环中的每个对象创建一个新行。
该函数接受一个 ZipOutputStream 和一个对象列表。
public ZipOutPutStream setStream(ZipoutputStream zos, List<Stores> storesList){
zos.setLevel(1);
newRow = new StringBuilder();
for (Stores s: storesList) {
//clearing the stringbuilder each iteration
newRow.setLength(0);
newRow.append(s.getId());
newRow.append(",")
.append(s.getTitle()).append(s.getDescription());
newRow.append("\n");
}
byte[] data = result.toString().getBytes();
zos.write(data, 0, data.length);
zos.closeEntry();
zos.close();
return zos;
}
我应该改变什么才能处理非常大的列表?
当您可以直接传输相同的数据时,不要构建内存结构 - 因为巨大的结构可能会在 toString()
或 getBytes()
调用时命中 OutOfMemoryError
。
如果您正在处理平台行分隔符,您可以这样写行:
PrintWriter w = new PrintWriter(zos/*,false, orCharSetHere*/);
for (Stores s : storesList) {
w.println(s.getId() + "," + s.getTitle() + s.getDescription());
}
w.flush();
但是如果您想要所有平台的 \n
行分隔符,可以使用以下方式发送行:
OutputStreamWriter w = new OutputStreamWriter(zos/*, orCharSetHere*/);
for (Stores s : storesList) {
w.write(s.getId() + "," + s.getTitle() + s.getDescription()+"\n");
}
w.flush();
必须刷新写入程序以确保在关闭 zip 条目或流之前将任何缓冲数据写入 ZipOutputStream
。