Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
谁杀了我的Java无限循环线程?_Java_Multithreading_Memory Management_Jvm_Kafka Consumer Api - Fatal编程技术网

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

谁杀了我的Java无限循环线程?,java,multithreading,memory-management,jvm,kafka-consumer-api,Java,Multithreading,Memory Management,Jvm,Kafka Consumer Api,正如标题所示,我将一些代码包装在while(true)无限循环中,所有代码都被try和catch块完全捕获。这个线程是在main方法中启动的,但是,在长时间运行之后,当我使用jstack检查时,这个工作线程神秘地消失了,导致工作累积 下面是我的代码: public void run() { while (true) { try { // Consumer consumes from Kafka server Global.K

正如标题所示,我将一些代码包装在
while(true)
无限循环中,所有代码都被
try
catch
块完全捕获。这个线程是在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()方法失败,它也会无限地重新启动。但是,正如我上面提到的,整个线程在没有任何错误日志的情况下悄无声息地消失。有人能提供一些线索吗

更多可能有用的信息:

  • 我已经检查了consume方法将永远不会关闭使用者 也不要关闭服务器的套接字。它将继续努力 失败后连接服务器
  • 我分析了java堆转储,发现内存泄漏 在项目中的其他地方,导致内存占用 高和gc非常常见。然而,主要的方法仍然是 跑步

  • 您正在捕获
    异常
    ,因此有可能抛出
    java.lang.Error
    java.lang.Throwable
    (例如)


    如果您真的想捕获所有内容,那么您需要捕获可丢弃的
    ,而不仅仅是
    异常
    子类。

    您的线程可能被错误终止

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

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

    决不应捕获可丢弃的内容,因为错误需要与异常不同的处理

    不是异常。这是一个从可丢弃性衍生出来的错误


    如果在您的
    消费(主题,处理程序)
    中的某个地方抛出了finally,那么finally仍将被调用,将不可避免的延迟大约30秒。。。但在此之后,错误将向上传递,循环将终止。

    您不应直接使用
    线程
    ;使用
    ExecutorService
    (在您的情况下,甚至可能使用
    ScheduledExecutorService
    )。另外,捕获
    Exception
    通常是个坏主意——您甚至可以捕获所有
    RuntimeException
    。但是您没有捕捉到
    错误
    s。这里可能发生的情况是,您触发了一个触发循环结束的
    OutOfMemoryError
    。一般来说,您应该检查您的设计。此外,您可以使用
    TimeUnit.SECONDS.sleep(30L)
    ,而不是
    Thread.sleep()
    ;但无论如何,一定要使用
    ScheduledExecutorService
    。不要捕获可丢弃的
    。至少不在这个循环中。这会导致严重的麻烦。一个
    错误
    应该正确处理,而不仅仅是忽略。谢谢!这解释了很多。然而,我很困惑OutOfMemoryError会被抛出到哪里?它会在代码中任意位置随机抛出吗?我已经在这个项目上玩了好几次,每次只有这个线程被终止。那一定是什么原因吧?还有,你能解释一下为什么错误不应该被发现吗?我们应该如何“恰当地”处理它@现实怀疑论者