java-Springboot与@Transactional Quartz作业一起导致内存泄漏
将springboot(2.4.5)与springboot starter quartz依赖项相结合时,我在尝试强制执行时遇到了内存泄漏问题Job.execute(JobExecutionContext context)
成为@Transactional
因为我需要在那里进行一些延迟加载,尽管我演示的示例中的问题是没有进行任何加载,但仍然会产生泄漏。
我听从了学校的指导巴东跳石英表,其中我实现的结果是下面的类,我为&;将其安排在应用程序的其他位置(irelevant where)。
@Slf4j
@Component
public class FakeQuartzJob extends Job {
@Override
@Transactional
public void execute(JobExecutionContext context) {
log.info("I was called");
}
public static Trigger buildJobTrigger(JobDetail jobDetail) {
return TriggerBuilder.newTrigger()
.forJob(jobDetail)
.withIdentity(UUID.randomUUID().toString(), "fake-job-trigger")
.startAt(Date.from(Instant.now().plusSeconds(1)))
.withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withMisfireHandlingInstructionFireNow())
.build();
}
public static JobDetail buildJobDetail() {
JobDataMap jobDataMap = new JobDataMap();
jobDataMap.put("someRandomData", new FakeDataClass());
return JobBuilder.newJob(FakeQuartzJob.class)
.withIdentity(UUID.randomUUID().toString(), "fake-job-detail")
.usingJobData(jobDataMap)
.build();
}
}
这将导致为服务器创建事务代理FakeQuartzJob.execute
方法(应该是transactional),但在进行堆调查时,我发现它会将此代理发布到spring容器bean注册表中,但它从未从注册表中删除,请参阅
这些代理永远不会被垃圾收集,这会导致堆内存不断被垃圾吞噬,直到达到极限,应用程序停止运行。
我就这个问题测试了spring/quartz合作的不同行为/组合
-
@Autowire将服务/repos bean添加到作业中没有问题
-
自动接线和呼叫没有问题
Job.execute
如果没有@Transactional
注释 -
使用时出现问题
@Transactional
在里面Job.execute(JobExecutionContext context)
我期望并且迫切需要的是,在执行quartz作业时,能够对实体关系进行hibernate延迟加载,但为此,我需要通过@Transactional
.
我知道我正在安排这项工作,而它是用@Component
,所以当类被构造时,它就变成了spring管理的,但我这样做是为了允许自动连接。
我完全不明白的是,为什么spring不释放代理类,并一直保留对它们的引用(类代理由方法代理引用),请参见
Spring&Quartz问题:有没有一种方法既可以自动布线,又可以进行自动布线@Transactional
执行任务时打电话?
技术问题当前位置发生这种情况的原因可能是什么?