quartz多次执行后,Java Excel POI停止

quartz多次执行后,Java Excel POI停止,java,profiling,apache-poi,quartz-scheduler,Java,Profiling,Apache Poi,Quartz Scheduler,我想在这方面有一些见解 我有一个程序,可以从数据库读写excel文件。它的执行基于使用Quartz api的计时器,并在每周的每个星期二触发。问题是,当我通过安排它每小时执行一次作业来测试它时,程序在编写excel文件的过程中执行了几次之后突然停止。这是我写的excel代码 try { FileInputStream file = new FileInputStream(excelFile); POIFSFileSystem myFileSystem = new

我想在这方面有一些见解

我有一个程序,可以从数据库读写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
工作呢

public class ExtractorSchedulerJobUtilTester implements Job {
    public void execute(JobExecutionContext context)
        throws JobExecutionException {
    theProgram program= new theProgram();

    program.main();

    JobKey jobKey = context.getJobDetail().getKey();
    }
}
有没有可能,

  • 应用程序正在耗尽我的内存并崩溃
  • 在我的Quartz作业中,我只使用了一个“program”实例,该实例在作业第一次运行时初始化,作业的所有后续执行都从该实例引用,从而耗尽了内存
  • 它与数据库(AS400)相关(我怀疑,因为它在编写excel时会停止)
  • 电脑太累了,决定休息一下 更新-2012年12月28日

    祝各位新年快乐

    对不起,我花了一些时间才回到这件事上。。(当世界将在21日结束的时候,为什么还要在这件事上浪费时间呢。没有结束的时候是苦乐参半的。)

    我用netbeans分析器分析了我的程序,并用内存分析器得到了以下数据

    我在第一个图中注意到,我的程序在每次迭代中消耗大约75MB的堆大小(如粉色阴影所示)。这是否意味着每次迭代程序消耗的内存会增加75mb?经过几次迭代后,将消耗大量内存,从而影响程序的执行。我目前正在尝试进行堆转储。。我会尽快把它发出去

    附加信息:我试着只在Quartz运行的情况下使用探查器(不会触发任何事件),系统使用率相对较低,并且每次迭代的大小都不会增加

    我终于设法得到了一个堆转储。我做了两次转储,第一次是在第一次迭代时,第二次是下一次迭代。我注意到我的两个同学的例子有很大的不同,如下所示


    谢谢

    经过大量的咒骂、祈祷和搜索,我想我已经找到了一个可能的解决办法。我所做的是添加
    System.gc()在我的石英作业课结束时。因此,每次程序完成任务时都调用垃圾回收。这只是一个可能的解决方案,而不是一个具体的答案,因为我仍然在消耗大量的堆内存(我相信在我混乱的代码中仍然有一些内存泄漏)。但是,使用
    System.gc()我的消费量大大减少了。我只是不知道这是怎么发生的。从逻辑上讲,我认为GC只会影响内存分配,而不会影响程序的内存性能。见下图;顶部的图形是有GC的图形,底部的图形是没有GC的图形


    正如您所看到的,有GC的堆内存消耗比没有GC的更少。我假设GC的内存使用率仍然相同,但一旦调用了GC,使用的堆空间就会减少。我现在将使用此解决方案,直到出现更好的答案。

    评测有什么指导吗?你每次都在启动一个新的虚拟机吗?还可以看到这个吗?调度程序是如何执行程序的?使用
    java
    命令行启动一个新的VM,还是只导入程序的java类并运行?尝试使计划程序每5或10分钟运行一次以进行调试。检查此问题()以了解如何转储JVM崩溃日志。@AlexCheng。我只是导入类并将其作为作业运行。使用jdk的jstack工具创建几个线程转储。当程序挂起时,你应该能够确定你的线程在做什么。从你所提到的来看,excel代码看起来不错。我对触发部分持怀疑态度。通过制作自己的小型调度程序来尝试。i、 例如,以石英为例,让一个线程运行任务并休眠2分钟,然后继续并重复大约20次。如果工作正常,那么问题在于石英
    public class ExtractorSchedulerJobUtilTester implements Job {
        public void execute(JobExecutionContext context)
            throws JobExecutionException {
        theProgram program= new theProgram();
    
        program.main();
    
        JobKey jobKey = context.getJobDetail().getKey();
        }
    }