请提供有关如何击败 java.lang.OutOfMemoryException: java heap space 的建议。
PC上的RAM是8GB,我做了设置-Xms7G,我无法通过。具有 8GB 标准的 MacBook 上的主要功能。
本质是我从 xlsx 表单加载了大约 9000 行,正好落在 XSSFSheet.read 方法上。如果您在此文件中保留 5 行,则一切正常。
load 方法本身会为每一行创建一个对象。
rateClass = new RateClass(разные параметры, около 10 штук);
if (!mapOfRates.containsValue(rateClass)) {
mapOfRates.put(i, rateClass);
i++;
}
rateClass = null;
有人能告诉我为什么会这样吗((在更强大的机器上,16GB 的 RAM 和核心 i7 一切正常。
@Service
@Component
public class GetListOfRatesImpl implements GetList {
// Подключаем логгер
private static Logger logger = LoggerFactory.getLogger(GetListOfRatesImpl.class);
// Основаная мапа, куда записываем все маршруты
private Map<Integer, RateClass> mapOfRates = new HashMap<>();
// Переменные для работы с файлами
private File file;
private FileInputStream fileInputStream;
// Переменные для работы с Excel файлом(формат XLSX)
private XSSFWorkbook xssfWorkbook;
private XSSFSheet sheet;
RateClass rateClass = null;
private GetListOfRatesImpl() {
}
@Override
public void fillMap() {
mapOfRates.clear();
// Получаем файл формата xls
try {
fileInputStream = new FileInputStream(this.file);
xssfWorkbook = new XSSFWorkbook(fileInputStream);
// Заполняем Map данными
sheet = xssfWorkbook.getSheetAt(0);
int i = 0;
for (int j = 1; j < sheet.getLastRowNum() + 1; j++) {
XSSFRow row = sheet.getRow(0);
String nameOfStationDeparture = null;
String nameOfStationDestination = null;
String customer = null;
double rate = 0.00d;
Date dateLoading = null;
String nameCargo = null;
String keyCargo = null;
for (int c = 0; c < row.getLastCellNum(); c++) {
if (row.getCell(c).getStringCellValue().trim().equals(JavaHelperBase.RATE_NAME_STATION_DEPARTURE)) {
XSSFRow xssfRow = sheet.getRow(j);
nameOfStationDeparture = xssfRow.getCell(c).getStringCellValue();
}
if (row.getCell(c).getStringCellValue().trim().equals(JavaHelperBase.RATE_NAME_STATION_DESTINATION)) {
XSSFRow xssfRow = sheet.getRow(j);
nameOfStationDestination = xssfRow.getCell(c).getStringCellValue();
}
if (row.getCell(c).getStringCellValue().trim().equals(JavaHelperBase.RATE_CUSTOMER)) {
XSSFRow xssfRow = sheet.getRow(j);
customer = xssfRow.getCell(c).getStringCellValue();
}
if (row.getCell(c).getStringCellValue().trim().equals(JavaHelperBase.RATE_NAME_CARGO)) {
XSSFRow xssfRow = sheet.getRow(j);
nameCargo = xssfRow.getCell(c).getStringCellValue();
}
if (row.getCell(c).getStringCellValue().trim().equals(JavaHelperBase.RATE_KEY_CARGO)) {
XSSFRow xssfRow = sheet.getRow(j);
if (xssfRow.getCell(c).getCellTypeEnum().equals(CellType.NUMERIC)) {
String val = Double.toString(xssfRow.getCell(c).getNumericCellValue());
double valueDouble = xssfRow.getCell(c).getNumericCellValue();
if ((valueDouble - (int) valueDouble) * 1000 == 0) {
val = (int) valueDouble + "";
}
keyCargo = val;
} else {
keyCargo = xssfRow.getCell(c).getStringCellValue();
}
}
if (row.getCell(c).getStringCellValue().trim().equals(JavaHelperBase.RATE_RATE)) {
XSSFRow xssfRow = sheet.getRow(j);
rate = xssfRow.getCell(c).getNumericCellValue();
}
if (row.getCell(c).getStringCellValue().trim().equals(JavaHelperBase.RATE_DATE_LOADING)) {
XSSFRow xssfRow = sheet.getRow(j);
dateLoading = xssfRow.getCell(c).getDateCellValue();
dateLoading.setHours(0);
dateLoading.setMinutes(0);
dateLoading.setSeconds(0);
if (dateLoading == null) dateLoading = new Date();
}
}
rateClass = new RateClass(nameOfStationDeparture, nameOfStationDestination, customer, nameCargo, keyCargo, rate, dateLoading);
if (!mapOfRates.containsValue(rateClass)) {
mapOfRates.put(i, rateClass);
i++;
}
rateClass = null;
}
logger.debug("Body rates: {}", mapOfRates);
} catch (IOException e) {
logger.error("Ошибка загруки файла - {}", e.getMessage());
} catch (OLE2NotOfficeXmlFileException e1) {
logger.error("Некорректный формат файла заявок, необходим формат xlsx");
}
}
public Map<Integer, RateClass> getMapOfRates() {
return mapOfRates;
}
public void setMapOfRates(Map<Integer, RateClass> mapOfRates) {
this.mapOfRates = mapOfRates;
}
public void setFile(File file) {
this.file = file;
fillMap();
}
}
速率等级
public class RateClass implements Comparable<RateClass> {
// Подключаем логгер
private static Logger logger = LoggerFactory.getLogger(Route.class);
private String nameOfStationDeparture; // Станция отправления
private String nameOfStationDestination; // Станция назначения
private String customer; // Заказчик
private CargoClass cargo; // Груз
private double rate; // Ставка
private Date loadingDate; // Дата погрузки
public RateClass(String nameOfStationDeparture, String nameOfStationDestination, String customer, String nameCargo, String keyCargo, double rate, Date loadingDate) {
this.nameOfStationDeparture = nameOfStationDeparture;
this.nameOfStationDestination = nameOfStationDestination;
this.customer = customer;
this.cargo = new CargoClass(nameCargo, keyCargo);
this.rate = rate;
this.loadingDate = loadingDate;
}
public String getNameOfStationDeparture() {
return nameOfStationDeparture;
}
public void setNameOfStationDeparture(String nameOfStationDeparture) {
this.nameOfStationDeparture = nameOfStationDeparture;
}
public String getNameOfStationDestination() {
return nameOfStationDestination;
}
public void setNameOfStationDestination(String nameOfStationDestination) {
this.nameOfStationDestination = nameOfStationDestination;
}
public String getCustomer() {
return customer;
}
public void setCustomer(String customer) {
this.customer = customer;
}
public CargoClass getCargo() {
return cargo;
}
public void setCargo(CargoClass cargo) {
this.cargo = cargo;
}
public double getRate() {
return rate;
}
public void setRate(double rate) {
this.rate = rate;
}
public Date getLoadingDate() {
return loadingDate;
}
public void setLoadingDate(Date loadingDate) {
this.loadingDate = loadingDate;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
RateClass rateClass = (RateClass) o;
return Double.compare(rateClass.rate, rate) == 0 &&
Objects.equals(nameOfStationDeparture, rateClass.nameOfStationDeparture) &&
Objects.equals(nameOfStationDestination, rateClass.nameOfStationDestination) &&
Objects.equals(customer, rateClass.customer) &&
Objects.equals(cargo, rateClass.cargo) &&
Objects.equals(loadingDate, rateClass.loadingDate);
}
@Override
public int hashCode() {
return Objects.hash(nameOfStationDeparture, nameOfStationDestination, customer, cargo, rate, loadingDate);
}
@Override
public String toString() {
return "RateClass{" +
"nameOfStationDeparture='" + nameOfStationDeparture + '\'' +
", nameOfStationDestination='" + nameOfStationDestination + '\'' +
", customer='" + customer + '\'' +
", cargo=" + cargo +
", rate=" + rate +
", loadingDate=" + loadingDate +
'}';
}
@Override
public int compareTo(RateClass o) {
return o.loadingDate.compareTo(this.loadingDate);
}
}
错误堆栈
java.lang.OutOfMemoryError: Java heap space
com.sun.org.apache.xerces.internal.dom.DeferredDocumentImpl.createChunk(Unknown Source)
com.sun.org.apache.xerces.internal.dom.DeferredDocumentImpl.ensureCapacity(Unknown Source)
com.sun.org.apache.xerces.internal.dom.DeferredDocumentImpl.createNode(Unknown Source)
com.sun.org.apache.xerces.internal.dom.DeferredDocumentImpl.createDeferredAttribute(Unknown Source)
com.sun.org.apache.xerces.internal.dom.DeferredDocumentImpl.setDeferredAttribute(Unknown Source)
com.sun.org.apache.xerces.internal.parsers.AbstractDOMParser.startElement(Unknown Source)
com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown Source)
com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(Unknown Source)
com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source)
com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source)
javax.xml.parsers.DocumentBuilder.parse(Unknown Source)
org.apache.poi.util.DocumentHelper.readDocument(DocumentHelper.java:140)
org.apache.poi.POIXMLTypeLoader.parse(POIXMLTypeLoader.java:163)
org.openxmlformats.schemas.spreadsheetml.x2006.main.WorksheetDocument$Factory.parse(Unknown Source)
org.apache.poi.xssf.usermodel.XSSFSheet.read(XSSFSheet.java:226)
org.apache.poi.xssf.usermodel.XSSFSheet.onDocumentRead(XSSFSheet.java:218)
org.apache.poi.xssf.usermodel.XSSFWorkbook.parseSheet(XSSFWorkbook.java:443)
org.apache.poi.xssf.usermodel.XSSFWorkbook.onDocumentRead(XSSFWorkbook.java:408)
org.apache.poi.POIXMLDocument.load(POIXMLDocument.java:169)
org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:300)
com.uraltranscom.dynamicdistributionpark.service.impl.GetListOfRatesImpl.fillMap(GetListOfRatesImpl.java:72)
com.uraltranscom.dynamicdistributionpark.service.impl.GetListOfRatesImpl.setFile(GetListOfRatesImpl.java:158)
com.uraltranscom.dynamicdistributionpark.controller.Controller.routeList(Controller.java:51)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
我不知道为什么要使用它
i,也许一个列表就足够了,private Map<Integer, RateClass> mapOfRates = new HashMap<>();或者只是该方法应该返回例如:public List<RateClass> getRateClass()或者public Set<RateClass> getRateClass()?您可以立即阅读文件
XSSFWorkbook xssfWorkbook = new XSSFWorkbook(file);您可以删除服务中的所有字段,它们不是特别需要
顺便说一句,如果不是区间-128 - 127 ,每个人都
getRow可以创建一个新的IntegerXSSFRow xssfRow = sheet.getRow(j);将其移动到循环上方的变量中?取出所有变量,从而避免创建不必要的对象,例如:
导入 org.apache.poi.openxml4j.exceptions.InvalidFormatException;导入 org.apache.poi.openxml4j.exceptions.OLE2NotOfficeXmlFileException;导入 org.apache.poi.ss.usermodel.CellType;导入 org.apache.poi.xssf.usermodel.XSSFCell;导入 org.apache.poi.xssf.usermodel.XSSFRow;导入 org.apache.poi.xssf.usermodel.XSSFSheet;导入 org.apache.poi.xssf.usermodel.XSSFWorkbook;导入 org.slf4j.Logger;导入 org.slf4j.LoggerFactory;导入 org.springframework.stereotype.Service;
导入java.io.File;导入 java.io.IOException;导入 java.util.ArrayList;导入 java.util.Date;导入 java.util.List;
@Service 公共类 GetListOfRatesImpl 实现 GetList {
}
keyCargo 有点困难?两次
cell.getNumericCellValue()顺便说一句,如果有一个臀部垃圾场,那么应该清楚哪些对象很多以及可以节省什么
找到原因了,机器有问题,我重装了JVM,一切正常,谢谢大家。