Java的Excel的POI石英多个执行后停止(Java Excel POI stops after

2019-07-04 00:51发布

我想有一对夫妇在这个见解。

我有一个程序,可以读取和写入数据库到Excel文件。 它的执行是基于使用Quartz API的定时器,触发了一周的每星期二。 问题是,当我通过安排其执行作业每隔一小时进行了测试,程序突然写入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是工作的一个无限循环......为了进一步了解更多的光​​线关于这个话题,这是我的计划的简要流程。

  1. 用户执行调度
  2. 在期望的时间调度执行程序(调度程序和“程序”是两个不同的程序/ jar文件。调度只是调用罐子)
  3. 该计划首先创建Excel文件
  4. 然后读取数据库1.该数据库包含80K行
  5. 对于每一行,如果某个条件满足时,它读取数据库2和3
  6. 它然后将其存储在一个时间一个ArrayList对象1000内(IM试图避免任何内存问题,所以我把它存储由一批)
  7. 然后我在时刻写它通过分批,1000到Excel(这是它停止的部分)
  8. 它完成了阅读和写作之后,它会等待直到调度再次调用它......如果做到了这一步,我是一个快乐的程序员=)

这里有一些意见,我发现;

  1. 该方案通常会停止在第4到程序的第六执行(这是后4或6小时运行调度器程序不停的)
  2. 它停在写在Excel中像在第34万余行或24日或15日等等等随机点...
  3. 当我没有调度执行程序不会发生此错误。 我可以没有任何错误手动执行它整天(我做到了,这不是很有趣)。
  4. 输出excel文件显示0bytes作为尺寸
  5. 例如,如果我定它为每小时运行,为此小时便停了下来。 它仍然会运行随后的几个小时,但将停止,并且在不同的点相比之前的运行停止。

什么原因可能造成这个问题。 内存泄漏可能或一些更简单吗?

附加信息

我通过导入类的其他程序的实施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();
    }
}

有没有可能;

  1. 该应用程序是杏我的记忆和崩溃
  2. 我只在其中在工作的第一次运行初始化和作业的所有后续执行是从一个实例引用这样杏内存我石英作业中使用“程序”的一个实例。
  3. 它的数据库(AS400)相关的(我怀疑,因为它,而它的写入Excel停止)。
  4. 计算机变得太累了,决定休息一下。

更新- 2012年12月28日

新年快乐家伙/三角旗号!

对不起,我花了一些时间来重新进入这个..(何必在此浪费时间,当世界上21会结束。这是苦乐参半的,当它没有)

我异型我与NetBeans配置方案,并得到了与内存分析器下图

我注意到在我的程序占用75MB左右的堆大小每次迭代(由粉红色光所示)第一张图。 这是否意味着方案增加消耗的内存每次迭代75MB? 其中,经过几次反复,会消耗这么多的内存,这将影响程序的执行。 我目前正试图采取堆转储。我会尽快发布它,因为我设法得到它运行。

附加信息:我尝试使用分析器只石英运行(不会触发任何东西)和系统使用率相对较低,且规模不增加每个迭代。

我终于得到了一个堆转储。 我花了2场,第一次是在第一次迭代发生,第二个是下一次迭代。 我注意到,有如下所示的我的两个类新的实例之间有很大的不同

谢谢!

Answer 1:

很多咒骂,祈祷和搜索之后,我想我已经找到了一个可能的解决方案这一点。 我所做的是增加System.gc(); 在我的石英作业类的结尾。 因此,调用垃圾收集每次程序完成的工作。 这只是一个可能的解决方案,而不是一个具体的答案,因为我还是吃了不少的堆内存(我相信还是有一些内存泄漏的地方在我的代码的混乱)。 但是,随着System.gc(); 我消耗相当少。 我只是不知道这是如何发生。 按道理我认为GC只会影响程序的内存分配,而不是内存性能。 见下面的图片; 顶部图形是一个与GC而底部是没有一个。

正如你可以看到一个与GC正在消耗比一个没有堆内存更少。 我认为内存使用率仍然会与GC相同,但一旦GC被称为使用的堆空间会有所下降。 我将使用这种解决方案现在,直到出现一个更好的答案。



文章来源: Java Excel POI stops after multiple execution by quartz