Ошибка размера кучи из ArrayList

У меня классная поездка

package com.firstgroup.bbrailapps.pushport.timetable;

import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElements;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import javax.xml.datatype.XMLGregorianCalendar;


/**
 * <p>Java class for anonymous complex type.
 * 
 * <p>The following schema fragment specifies the expected content contained within this class.
 * 
 * <pre>
 * &lt;complexType>
 *   &lt;complexContent>
 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       &lt;sequence>
 *         &lt;choice maxOccurs="unbounded" minOccurs="2">
 *           &lt;element ref="{http://www.thalesgroup.com/rtti/XmlTimetable/v7/rttiCTTSchema.xsd}OR"/>
 *           &lt;element ref="{http://www.thalesgroup.com/rtti/XmlTimetable/v7/rttiCTTSchema.xsd}IP"/>
 *           &lt;element ref="{http://www.thalesgroup.com/rtti/XmlTimetable/v7/rttiCTTSchema.xsd}DT"/>
 *           &lt;element ref="{http://www.thalesgroup.com/rtti/XmlTimetable/v7/rttiCTTSchema.xsd}PP"/>
 *         &lt;/choice>
 *         &lt;element ref="{http://www.thalesgroup.com/rtti/XmlTimetable/v7/rttiCTTSchema.xsd}AS" maxOccurs="unbounded" minOccurs="0"/>
 *       &lt;/sequence>
 *       &lt;attribute name="rid" use="required" type="{http://www.thalesgroup.com/rtti/XmlTimetable/v7/rttiCTTSchema.xsd}RIDType" />
 *       &lt;attribute name="uid" type="{http://www.thalesgroup.com/rtti/XmlTimetable/v7/rttiCTTSchema.xsd}UIDType" />
 *       &lt;attribute name="ssd" use="required" type="{http://www.thalesgroup.com/rtti/XmlTimetable/v7/rttiCTTSchema.xsd}RTTIDateType" />
 *       &lt;attribute name="trainId" type="{http://www.thalesgroup.com/rtti/XmlTimetable/v7/rttiCTTSchema.xsd}TrainIdType" />
 *       &lt;attribute name="toc" type="{http://www.thalesgroup.com/rtti/XmlTimetable/v7/rttiCTTSchema.xsd}TOCType" />
 *       &lt;attribute name="qtrain" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
 *       &lt;attribute name="status" use="required" type="{http://www.thalesgroup.com/rtti/XmlTimetable/v7/rttiCTTSchema.xsd}CIFTrainStatusType" />
 *       &lt;attribute name="trainCat" use="required" type="{http://www.thalesgroup.com/rtti/XmlTimetable/v7/rttiCTTSchema.xsd}CIFTrainCategoryType" />
 *       &lt;attribute name="deleted" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
 *       &lt;attribute name="can" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
 *     &lt;/restriction>
 *   &lt;/complexContent>
 * &lt;/complexType>
 * </pre>
 * 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "orOrIPOrDT",
    "as"
})
@XmlRootElement(name = "Journey")
public class Journey {

    @XmlElements({
        @XmlElement(name = "OR", type = OR.class),
        @XmlElement(name = "PP", type = PP.class),
        @XmlElement(name = "IP", type = IP.class),
        @XmlElement(name = "DT", type = DT.class)
    })
    protected List<Object> orOrIPOrDT;
    @XmlElement(name = "AS")
    protected List<AS> as;
    @XmlAttribute(required = true)
    protected String rid;
    @XmlAttribute
    protected String uid;
    @XmlAttribute(required = true)
    protected String ssd;
    @XmlAttribute
    protected String trainId;
    @XmlAttribute
    protected String toc;
    @XmlAttribute
    protected Boolean qtrain;
    @XmlAttribute(required = true)
    protected String status;
    @XmlAttribute(required = true)
    protected String trainCat;
    @XmlAttribute
    protected Boolean deleted;
    @XmlAttribute
    protected Boolean can;

    /**
     * Gets the value of the orOrIPOrDT property.
     * 
     * <p>
     * This accessor method returns a reference to the live list,
     * not a snapshot. Therefore any modification you make to the
     * returned list will be present inside the JAXB object.
     * This is why there is not a <CODE>set</CODE> method for the orOrIPOrDT property.
     * 
     * <p>
     * For example, to add a new item, do as follows:
     * <pre>
     *    getOROrIPOrDT().add(newItem);
     * </pre>
     * 
     * 
     * <p>
     * Objects of the following type(s) are allowed in the list
     * {@link OR }
     * {@link PP }
     * {@link IP }
     * {@link DT }
     * 
     * 
     */
    public List<Object> getOROrIPOrDT() {
        if (orOrIPOrDT == null) {
            orOrIPOrDT = new ArrayList<Object>();
        }
        return this.orOrIPOrDT;
    }

    /**
     * Gets the value of the as property.
     * 
     * <p>
     * This accessor method returns a reference to the live list,
     * not a snapshot. Therefore any modification you make to the
     * returned list will be present inside the JAXB object.
     * This is why there is not a <CODE>set</CODE> method for the as property.
     * 
     * <p>
     * For example, to add a new item, do as follows:
     * <pre>
     *    getAS().add(newItem);
     * </pre>
     * 
     * 
     * <p>
     * Objects of the following type(s) are allowed in the list
     * {@link AS }
     * 
     * 
     */
    public List<AS> getAS() {
        if (as == null) {
            as = new ArrayList<AS>();
        }
        return this.as;
    }

    /**
     * Gets the value of the rid property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getRid() {
        return rid;
    }

    /**
     * Sets the value of the rid property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setRid(String value) {
        this.rid = value;
    }

    /**
     * Gets the value of the uid property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getUid() {
        return uid;
    }

    /**
     * Sets the value of the uid property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setUid(String value) {
        this.uid = value;
    }

    /**
     * Gets the value of the ssd property.
     * 
     * @return
     *     possible object is
     *     {@link XMLGregorianCalendar }
     *     
     */
    public String getSsd() {
        return ssd;
    }

    /**
     * Sets the value of the ssd property.
     * 
     * @param value
     *     allowed object is
     *     {@link XMLGregorianCalendar }
     *     
     */
    public void setSsd(String value) {
        this.ssd = value;
    }

    /**
     * Gets the value of the trainId property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getTrainId() {
        return trainId;
    }

    /**
     * Sets the value of the trainId property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setTrainId(String value) {
        this.trainId = value;
    }

    /**
     * Gets the value of the toc property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getToc() {
        return toc;
    }

    /**
     * Sets the value of the toc property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setToc(String value) {
        this.toc = value;
    }

    /**
     * Gets the value of the qtrain property.
     * 
     * @return
     *     possible object is
     *     {@link Boolean }
     *     
     */
    public Boolean isQtrain() {
            return qtrain;
    }

    /**
     * Sets the value of the qtrain property.
     * 
     * @param value
     *     allowed object is
     *     {@link Boolean }
     *     
     */
    public void setQtrain(Boolean value) {
        this.qtrain = value;
    }

    /**
     * Gets the value of the status property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getStatus() {
        return status;
    }

    /**
     * Sets the value of the status property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setStatus(String value) {
        this.status = value;
    }

    /**
     * Gets the value of the trainCat property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getTrainCat() {
        return trainCat;
    }

    /**
     * Sets the value of the trainCat property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setTrainCat(String value) {
        this.trainCat = value;
    }

    /**
     * Gets the value of the deleted property.
     * 
     * @return
     *     possible object is
     *     {@link Boolean }
     *     
     */
    public Boolean isDeleted() {
            return deleted;
    }

    /**
     * Sets the value of the deleted property.
     * 
     * @param value
     *     allowed object is
     *     {@link Boolean }
     *     
     */
    public void setDeleted(Boolean value) {
        this.deleted = value;
    }

    /**
     * Gets the value of the can property.
     * 
     * @return
     *     possible object is
     *     {@link Boolean }
     *     
     */
    public Boolean isCan() {
            return can;
    }

    /**
     * Sets the value of the can property.
     * 
     * @param value
     *     allowed object is
     *     {@link Boolean }
     *     
     */
    public void setCan(Boolean value) {
        this.can = value;
    }

}

когда я добавляю около 60000 объектов класса путешествий в arraylist. Это дает ошибку java.lang.outofmemory, и я увеличил максимальный размер до 1 ГБ размера кучи. Есть ли какая-либо другая опция, кроме ArrayList для больших элементов.

1 ответ

ArrayList как таковая, вероятно, не проблема; это просто больше шансов сломаться, так как ArrayList выделяет в два раза больше размера массива, когда вы добавляете больше элементов, чем может содержать текущий массив, то есть, когда внутренний массив элементов заполнен, он удваивает массив и копирует все заново. Так что на короткое время понадобится size()*3 раз памяти (фактические цифры немного отличаются, но вы поняли).

Вы можете использовать другие списки, но им нужно еще больше памяти, но небольшими порциями.

Ошибка выше также зависит от размера каждого Journey объект. 60 КБ объектов не так много, но если каждый из них по 10 КБ, то для этого требуется 600 МБ или 60% от 1 ГБ, которые вы дали Java VM.

обходные:

  1. Вместо того, чтобы хранить весь объект в оперативной памяти, запомните начальную и конечную позиции в файле. Это займет всего несколько байтов. Когда кто-то запрашивает объект, используйте RandomFileAccess читать только XML для одного путешествия и анализировать его.

  2. Вместо того чтобы хранить все объекты в памяти, поместите данные в базу данных.

Другие вопросы по тегам