之前写的一个定时任务,频率一秒一次,常执行。
里面的业务代码比较复杂,有DB查询、DB更新和插入、有嵌套循环、还有调用图片处理的程序等等,放服务器上跑,大概40分钟,就吃掉很多内存,占比85%,再跑下去JVM就越界,导致内存溢出,服务器就启动自我保护自动重启了。
然后就开始排查程序,为什么在JAVA自动回收的情况下,还会把服务器玩坏,突然想到了定时任务的机制问题。
Spring的定时器:@Scheduled(cron = "0/1 * * * * ?"),默认是同步的还是异步的?因为业务代码的复杂性,单次执行往往要超过一秒,如果定时器是异步执行的,也就是说我上一次代码还没有跑完,下一次执行就开始了,时间长了,就会白给。如果是同步执行,下一次执行需要等待上一次执行完毕,那就不会出现,按照情况来说,我一开始认为我的内存溢出问题,就是定时器异步导致的。于是我做了实验。
默认测试:
@Service
@Lazy(false)
public class TestController {
@Scheduled(cron = "0/1 * * * * ?") // 间隔1秒
protected void executeTask() {
try{
for (int i = 0; i < 5; i++) {
System.out.println("i=" + i);
Thread.sleep(1000);
}
} catch (In