gpt4 book ai didi

java - 通过 quartz 多次执行后,Java Excel POI停止

转载 作者:搜寻专家 更新时间:2023-11-01 00:57:32 27 4
gpt4 key购买 nike

我想对此有一些见解。

我有一个程序,可以从数据库读取和写入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正在无限循环中工作...为了阐明更多信息关于这个话题,这是我程序的简要流程。
  • 用户执行调度程序
  • 在所需的时间,调度程序执行程序(调度程序和“程序”是两个不同的程序/jar文件。调度程序仅调用jar)
  • 该程序从创建excel文件
  • 开始
  • 然后读取数据库1。该数据库包含80K行
  • 对于每一行,如果满足特定条件,它将读取数据库2和3
  • 然后将它一次一次存储在一个arraylist对象1000中(我正试图避免任何内存问题,所以我按批次存储它)
  • 然后我一次批量地将其写为excel(这是它停止的部分),每次一次1000
  • 完成读写之后,等待调度程序再次调用...如果到达此步骤,我是一个快乐的程序员=)

  • 这是我发现的一些观察结果。
  • 程序通常在执行程序的第4到第6次执行时停止(即不间断运行调度程序4或6个小时)
  • 它会在excel中的随机写入点停止,例如在第3.4万行或第24或第15等,等等...
  • 当我在没有调度程序的情况下执行程序时,不会发生此错误。我可以整天手动执行它(我做了,那不是很有趣),没有任何错误。
  • 输出的excel文件显示0字节作为
  • 的大小
  • 例如,如果我将其计划为每小时运行一次,并且在这一小时内停止运行。它将继续运行接下来的几个小时,但将停止运行,并在与上次运行不同的时间点停止。

  • 是什么引起了这个问题。可能是内存泄漏或更简单?

    附加信息

    我通过导入其他程序的类并作为作业运行它来实现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();
    }
    }

    有可能吗?
  • 该应用程序占用了我的全部内存,并导致
  • 崩溃
  • 我只在Quartz作业中使用一个“程序”实例,该实例在该作业的第一次运行时初始化,并且该实例的所有后续执行均从该实例引用,从而使内存最大。
  • 与数据库(AS400)相关(我怀疑,因为它在编写excel时停止了)。
  • 计算机变得太累了,决定休息一下。

  • 更新-2012年12月28日

    新年快乐!

    抱歉,我花了一些时间才回到这个问题上。(为什么在21世纪世界终结时会为此浪费时间,而在21世纪末却真是苦乐参半)

    我使用netbeans profiler对程序进行了概要分析,并使用内存分析器获得了以下数据

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

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

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



    谢谢!

    最佳答案

    经过大量的咒骂,祈祷和搜查,我想我找到了一个可能的解决方案。我所做的是在Quartz作业类的末尾添加System.gc();。因此,在程序每次完成作业时都调用垃圾回收。这只是一个可能的解决方案,而不是一个具体的答案,因为我仍然在吃大量的堆内存(我相信代码困惑中的某个地方仍然存在一些内存泄漏)。但是,有了System.gc();,我的消耗就大大减少了。我只是不确定这是怎么发生的。从逻辑上讲,我认为GC仅会影响程序的内存分配,而不会影响程序的内存性能。见下图;上图是带有GC的图,下图是没有GC的图。



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

    关于java - 通过 quartz 多次执行后,Java Excel POI停止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13488893/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com