向ArrayList添加新对象会导致内存泄漏吗?

时间:2015-01-10 11:17:56

标签: java arraylist memory-leaks javacv

每当我尝试将新问题添加到问题的ArrayList时,它就会泄漏内存。在Question类的构造函数中,我创建了五个新的Rectangle对象。有趣的是,当我在Question类的构造函数中注释掉五个新的Rectangle时,本机内存会至少停止泄漏400 MB。当我运行JProfiler时,堆大小保持一致,但任务管理器显示正在使用超过700兆字节的内存。

以下是问题类的构造函数

public Question(int number,int options,IplImage in,String imgname,int unit,Point orig, JsonArray cells, JsonArray rows, int avgr) throws CellsWrongDetection{
    nu  = number;
    this.imgname = imgname;
    totOpt  = options;
    this.cells = cells;
    this.rows = rows;
    this.avgr = avgr;
    optA = new Rectangle(in);
    optB = new Rectangle(in);
    optC = new Rectangle(in);
    optD = new Rectangle(in);
    optE = new Rectangle(in);
    optF = new Rectangle(in);
    tmpimgx = in;
    setoptloc();
    //drawmaps();
}

这是我在ArrayList

中添加问题的地方
public void addAllQuestions(int[] options,String imgname) throws CellsWrongDetection{
    for (int i = 0; i < total; i++) {
        Question q=new Question(i, options[i], image, imgname, unit, orig, cells, rows, avgr);
        questions.add(q);

    }

}

这是矩形类

public class Rectangle extends Config{
private IplImage in;
public CvPoint tl,br;
public Rectangle(IplImage in){
    this.in = in;

}
public Rectangle()
{

}


public boolean isBlack(){
    double b=0,w=0;
    for (int y = tl.y(); y < br.y(); y++) {
        for (int x = tl.x(); x < br.x(); x++) {
            if (isblackp(x,y)) b++;
            else w++;
        }
    }
    double per = (b/w)*100 ;
    return (per <= percent)?false:true;
}
/***
 * Setting Edges points
 * @param p1 top-left corner
 * @param p2 bottom-right corner
 */
public void setCorn(CvPoint p1, CvPoint p2) {
    tl = p1;
    br = p2;
}
public void setCorn(int x0,int y0,int x1,int y1){
    //System.out.println("Setting points x0= "+x0+",y0="+y0+",x1= "+x1+",y1="+y1);
    CvPoint p1 = new CvPoint(),
            p2 = new CvPoint();
    p1.x(x0);p1.y(y0);
    p2.x(x1);p2.y(y1);
    setCorn(p1, p2);
}
public String displayCorners(){
    return "TopLeft ("+tl.x()+","+tl.y()+") BottomRight ("+br.x()+","+br.y()+")";
}
public double getheight(){
    return br.x() - tl.x();
}
public double getwidth(){
    return br.y() - tl.y();
}
/*
 * Detecting if pixel is black
 * @return boolean
 */
public boolean isblackp(int x,int y){
    CvScalar s=cvGet2D(in,y,x);
    in.release();
    cvReleaseImage(in);
    //System.out.println( "B:"+ s.val(0) + " G:" + s.val(1) + " R:" + s.val(2));//Print values
    return (s.val(2) <= cB && s.val(0) <= cG
            && s.val(1) <= cR)?true :false;
}

} 编辑: 列表在控制器中清除。

        for ( File file : filesInDirectory ) {

                if(isCancelled()){
                    view.dialog.setVisible(false);

                    return null;
                }

                view.SetNumerator(++index);
                String curimgname = file.getName();
                logger.log(Level.INFO,"Selected file "+curimgname);

                try {

                    sheet = new OmrModel(fh);
                    setProgress(0);


                    sheet.setpaths(curimgname, directory.toString());
                    setProgress(5);

                    sheet.init();
                    setProgress(10);


                    sheet.lookref("first");
                    setProgress(20);
                    sheet.scale();
                    sheet.lookref("second");
                    setProgress(25);
                    initDocs();
                    setProgress(30);

                    sheet.circle();
                    setProgress(40);

                    initQuestions(sheet.getQuestions(),sheet.getoptions(),sheet.getcols(),sheet.getrows(),sheet.avgr());

                    setProgress(50);

                    String[] results = sheet.getresults();
                    setProgress(60);

                    sheet.ClearQuestions();

                    sheet.drawgrid();
                    setProgress(70);

                    outcsv.println(curimgname+","+Arrays.toString(results));
                    setProgress(80);

                    genrslt(docs,sheet.getstudent(),"OMR", results);
                    setProgress(90);

                    //docs.push();
                    setProgress(100);
                    //movefile(file.getPath(),0);
                    System.gc();
                    System.out.println("Relaseing");
                    setProgress(100);
                    sheet.release();
                    publish(curimgname+"#"+sheet.getQrCode()+"#success");
                } catch (UnableToDetectOptions | WrongFileAttributes | UnableToLoadImage | UnableToDetectMarkers | MappingNotCorrect | WrongMarkers e1){
                    publish(curimgname+"#"+sheet.getQrCode()+"#"+e1.getMessage());
                    sheet.release();
                    //movefile(file.getPath(),-1);

                }

                catch (CouchDbException e2){
                    publish(curimgname+"#"+sheet.getQrCode()+"#Error Code 13");
                    //movefile(file.getPath(),-1);
                    sheet.release();
                } catch (RuntimeException e2){
                    e2.printStackTrace();
                    publish(curimgname+"#"+sheet.getQrCode()+"#Error Code 7");
                    sheet.release();
                    //movefile(file.getPath(),-1);
                } catch (CancelException | QrFailedToDetect e1){
                    publish(curimgname+"# #Error Code"+e1.getMessage());
                    //movefile(file.getPath(),1);
                    sheet.release();
                }
                catch(OutOfMemoryError e4)
                {
                    e4.printStackTrace();   
                    sheet.release();
                }


            }
            return null;

1 个答案:

答案 0 :(得分:1)

你没有泄露记忆;只有在接近内存不足时,java GC才能有效地释放不可到达(未使用)的对象;因此,即使比活动对象实际使用的数量少10倍,您也可以在任务管理器中看到1GB。