每当我尝试将新问题添加到问题的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;
答案 0 :(得分:1)
你没有泄露记忆;只有在接近内存不足时,java GC才能有效地释放不可到达(未使用)的对象;因此,即使比活动对象实际使用的数量少10倍,您也可以在任务管理器中看到1GB。