【问题标题】:Who killed My Java Infinite loop thread?谁杀死了我的 Java 无限循环线程?
【发布时间】:2016-02-29 10:20:57
【问题描述】:

正如标题所暗示的,我有一些代码包裹在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 heap dump,发现有内存泄漏 项目中的其他地方,导致内存占用极大 高和 gc 经常。但是,主要方法仍然是 正在运行。

【问题讨论】:

  • 你不应该直接使用Thread;改用ExecutorService(在你的情况下甚至可能是ScheduledExecutorService)。此外,捕获Exception 通常是个坏主意——您甚至捕获所有RuntimeException。但是......你没有抓住Errors。这里可能发生的是你触发了一个OutOfMemoryError,它触发了循环结束。更一般地,您应该审查您的设计。
  • 另外,你可以使用TimeUnit.SECONDS.sleep(30L),而不是Thread.sleep();但无论如何都要使用ScheduledExecutorService

标签: java multithreading memory-management jvm kafka-consumer-api


【解决方案1】:

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

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

【讨论】:

  • 谢谢!这解释了很多。但是,我对 OutOfMemoryError 会在哪里抛出感到困惑?它会随机抛出代码中的任何地方吗?我已经玩过这个项目好几次了,每次只有这个线程被杀死。那一定是有什么原因吧?而且,你能解释一下为什么不应该捕获错误吗?我们应该如何“妥善”处理? @RealSkeptic
【解决方案2】:

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

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

【讨论】:

  • 不要抓到Throwable。至少不在这个循环内。这可能会导致严重的麻烦。应该正确处理Error,而不仅仅是忽略。
【解决方案3】:

您的线程可能被错误杀死。

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

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

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

【讨论】:

    猜你喜欢
    • 2013-08-04
    • 1970-01-01
    • 1970-01-01
    • 2011-03-30
    • 2014-01-14
    • 2021-01-05
    • 1970-01-01
    • 2011-02-07
    • 1970-01-01
    相关资源
    最近更新 更多