谁杀死了我的 Java 无限循环线程?

Who killed My Java Infinite loop thread?

正如标题所暗示的,我有一些代码包裹在一个 while(true) 无限循环中,并且所有代码都被 trycatch 块完全捕获。这个线程是在main方法中启动的,但是,在运行之后,当我使用jstack检查时,这个工作线程神秘地消失了,导致工作积累。

下面是我的代码:

public void run() {
    while (true) {
        try {
            // Consumer consumes from Kafka server
            Global.KAFKA_METRIC_DATA_CONSUMER.consume(topic, handler);
        } catch (Exception e) {
            logger.error("Kafka consumer process was interrupted by exception!");
        } finally {
            try {
                // Prevent restart too often
                Thread.sleep(30 * BaseConst.SECOND);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

据我了解,此结构将保持线程 运行消费者也是如此。即使 consume() 方法失败,它也会无限重启。但是,正如我上面提到的,整个线程在没有任何错误日志的情况下悄无声息地消失了。谁能提供一些线索吗?

更多可能有用的信息:

  1. 我已经检查过消费方法永远不会关闭消费者 也不关闭服务器的套接字。它会不断尝试 失败后连接服务器。
  2. 我分析了 java 堆转储,发现存在内存泄漏 在项目的其他地方,导致内存占用极度 高而且gc很频繁。但是,主要方法仍然是 运行宁.

您正在捕捉 Exception,因此有可能抛出 java.lang.Errorjava.lang.Throwable(例如 OutOfMemoryError

如果您真的想捕获所有内容,则需要捕获 Throwable 而不仅仅是 Exception 个子类。

您的线程可能因错误而终止。

错误也不例外!但是它们都扩展了Throwable

添加另一个捕获错误的 catch 块。

Throwable 永远不应该被捕获,因为错误需要与异常不同的处理方式

OutOfMemoryError 不是例外。这是从 Throwable 派生的错误。

如果那是在你的 consume(topic, handler) 中的某个地方抛出的,finally 仍然会被调用,延迟不可避免的大约 30 秒......但之后错误将向上传递并且你的循环将被终止。