我想对此有一些见解。
我有一个程序,可以从数据库读取和写入excel文件。它的执行基于使用Quartz api的计时器,并在每周的每周二触发。问题是,当我通过安排它每小时执行一次作业来测试它时,程序在编写excel文件的过程中几次执行后突然停止。这是我写的excel代码。
try {
FileInputStream file = new FileInputStream(excelFile);
POIFSFileSystem myFileSystem = new POIFSFileSystem(file);
HSSFWorkbook workbook = new HSSFWorkbook(myFileSystem);
HSSFSheet worksheet = workbook.getSheetAt(0);
this.cellStyle00 = workbook.createCellStyle();
HSSFDataFormat df = workbook.createDataFormat();
this.cellStyle00.setDataFormat(df.getFormat("00"));
for(int i = 0;i<Access.size();i++){
AccessorMethods SetGet = (AccessorMethods)
InstlibAccessor.get(i);
HSSFRow row = worksheet.createRow(worksheet.getPhysicalNumberOfRows());
HSSFCell cell = row.createCell(0);
cell.setCellValue(new Double(SetGet.getOne()));
cell.setCellStyle(cellStyle00);
//other set value codes....
}
FileOutputStream fileOut = new FileOutputStream(fileName + ".xls");
workbook.write(fileOut);
fileOut.flush();
fileOut.close();
//catch statements follow
//end
命令行输出和netbeans输出并不表示任何错误,如内存不足等等。程序没有结束..它只是,停止..就像jvm正在进行无限循环...更多地了解这个话题,这是我的计划的简要流程。
以下是我发现的一些观察结果;
可能导致此问题的原因。内存泄漏或许更简单?
其他信息
我通过导入其他程序的类来实现Quartz调度程序并将其作为作业运行。这是触发器的代码
JobDetail job = newJob(ExtractorSchedulerJobUtilTester.class)
.withIdentity("job1", "group1")
.build();
CronTrigger trigger = newTrigger()
.withIdentity("trigger1", "group1")
.withSchedule(cronSchedule("0 0/2 * 1/1 * ? *"))
.build();
Date ft = sched.scheduleJob(job, trigger);
sched.start();
和工作
public class ExtractorSchedulerJobUtilTester implements Job {
public void execute(JobExecutionContext context)
throws JobExecutionException {
theProgram program= new theProgram();
program.main();
JobKey jobKey = context.getJobDetail().getKey();
}
}
是否可能;
更新 - 12/28/2012
新年快乐男孩/加尔斯!!
对不起,我花了一些时间才回到这里......(当世界将在21日结束时,为什么还要浪费时间。当它没有时它是苦乐参半的)
我用netbeans profiler描述了我的程序,并使用内存分析器获得了以下数据
我在第一张图中注意到,我的程序在每次迭代时消耗大约75MB的堆大小(如粉色阴影所示)。这是否意味着程序的消耗内存每次迭代增加75mb?经过几次迭代后,会占用大量内存,从而影响程序的执行。我正在尝试进行堆转储..一旦我设法让它运行,我就会发布它。
附加信息:我尝试使用仅运行Quartz的探测器(不会触发任何东西),系统使用率相对较低,每次迭代的大小都不会增加。
我终于设法获得堆转储。我进行了2次转储,首先是第一次迭代发生时,第二次是下一次迭代。我注意到我的两个classess的实例之间存在很大差异,如下所示
谢谢!
答案 0 :(得分:0)
经过大量的诅咒,祈祷和搜索后,我想我已经找到了解决方法。我所做的是在Quartz作业类的末尾添加System.gc();
。因此,每次程序完成作业时调用垃圾回收。这只是一个可能的解决方案,而不是一个具体的答案,因为我仍然占用了大量的堆内存(我相信在我的代码的混乱中仍有一些内存泄漏)。但是,System.gc();
我消耗的费用要少得多。我只是不确定这是怎么发生的。从逻辑上讲,我认为GC只会影响内存分配,而不会影响程序的内存性能。见下图;顶部的图表是带有GC的图表,而底部是没有的图表。
正如您所看到的那样,GC的堆内存比没有GC的堆内存少。我假设内存使用量仍与GC相同,但一旦调用GC,使用的堆空间将下降。我现在将使用这个解决方案,直到出现更好的答案。