Java 长 运行 计时器正在被 GC 消耗

Java long running timer is being consumed by GC

我有一个 java.util.Timer 并且我正在安排 TimerTasks 运行 每 24 小时 3:00:00 AM,但是在 5-8 天后,定时器被 GC 和我所有的消耗任务被取消,因为计时器实例不再存在。

我怎样才能避免这种情况?

我使用:

t.schedule(timerTask, date);

然后任务又开始了(当任务被执行时也调用了再次调度这个任务的方法)

定时器是这样定义的:

public static Timer t = new java.util.Timer();

static 变量是 class 的一部分,它们在其中定义并在 class 加载时初始化。 GC 可能会在某个时候决定(尤其是当内存不足并且挂起的操作需要更多内存时)卸载不再需要的 class。这就是你在这里可能会遇到的情况。您可以尝试创建 Timer 对象作为 class 的非静态成员,它保证有一个实例仍然被 GC 引用。

如果定时器是这样声明和创建的:

    public static Timer t = new java.util.Timer();

那么我认为只有两种情况Timer可以被垃圾回收:

  1. 在您的应用程序的某处,某些东西正在为 t 分配一个新值,导致以前的值变得无法访问。

  2. 包含 t 声明的 class 变得不可访问并已被卸载。

到目前为止,第一种情况最有可能发生,并且有一种简单的方法可以避免这种情况。将声明更改为:

   public static final Timer t = new java.util.Timer();

第二种情况只有在您的应用程序(或者可能是它正在使用的框架)使用本身变得无法访问的 class 加载程序动态加载 class 时才可能出现。