java - 将新对象添加到 ArrayList 会导致内存泄漏?

标签 java arraylist memory-leaks javacv

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

这是问题类的构造函数

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

} 编辑: 该列表在 Controller 中被清除。

        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;

最佳答案

您没有泄漏内存;只有当你快要用完内存时,java GC 才会有效地释放无法访问(未使用)的对象;因此,您可以在任务管理器中看到 1GB,即使它比 Activity 对象实际使用的空间少 10 倍。

关于java - 将新对象添加到 ArrayList 会导致内存泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27875623/

相关文章:

java - 如何比较数组中的值?

java - 是否可以更改java中继承类的 protected 变量?

java - 通过java从mysql的数据创建json对象

groovy - Groovy 中 2 个列表的内容求和

java - Java中使用Scanner时如何减少内存泄漏?

java - 查找字典单词的变位词

java - Android 1.5/1.6 问题与样式和自动生成的 R.java 文件

java - 通过从扫描仪中读取行来实例化一个 ArrayList,在哪里声明对象?

python - 对于小型/大型 numpy 数组,释放的处理方式是否不同?

c++ - 如何通过Valgrind查找QThreads程序中的内存泄漏位置?