ArrayList的堆大小错误

时间:2015-01-19 12:50:05

标签: java arraylist out-of-memory heap-size

我上课了

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;
    }

}

当我在arraylist中添加大约60,000个旅程类对象时。它给出了java.lang.outofmemory错误,并且我将最大大小增加到1GB的堆大小。对于大型元素,是否有除ArrayList之外的任何其他选项。

1 个答案:

答案 0 :(得分:0)

这样ArrayList可能不是问题;当你添加比当前数组可以包含的更多的元素时,ArrayList分配两倍数组大小更可能会破坏,即当元素的内部数组已满时,它将使数组加倍并复制所有内容。因此,在短时间内,它将需要size()*3倍的内存(实际数字略有不同,但你明白了)。

您可以使用其他列表,但它们需要更多内存,但需要更小的内存。

上述错误还取决于每个Journey对象的大小。 60K对象并不多,但如果每个对象都是10KB,则需要600 MB或60GB的Java VM。

解决方法:

  1. 不要将整个对象保留在RAM中,而是记住文件中的开始和结束位置。这只需几个字节。当有人请求对象时,使用RandomFileAccess只读取单行程的XML并解析它。

  2. 不是将所有对象都保存在内存中,而是将数据放入数据库中。