【问题标题】:Multithreaded application stops after 3 days多线程应用程序在 3 天后停止
【发布时间】:2011-07-05 15:57:32
【问题描述】:

我有一个获取不同网页的多线程应用程序。为此,我设计了线程之间的父子关系。 父级只是从其页面中获取不同的 url 并产生新线程。这些线程不断地获取页面,直到页面发生变化。主线程每 2 分钟轮询一次主页面的更改(如果有任何更改,则创建新线程)

主线程算法

while(true){
    find_new_instances(...);
    if we get any new, then
        Thread.start(...);
    Thread.sleep(120000);
}

主线程有一个字符串数组列表,用于存储它创建的每个新线程的 url。我听说线​​程应该只使用不可变对象进行写入。此处使用可变列表是否会导致问题? 在子线程中,进行页面获取和数据库插入等活动。

但是,应用程序会逐渐增加其内存需求并最终死锁/饿死到冻结状态或 OutOfMemory(如果不是)。的线程太大。 我无法尝试任何东西。如果您遇到过类似的问题,请提出建议。

【问题讨论】:

  • 线程数是多少?这个循环将在很短的时间内创建大量线程,并使每个线程休眠很长时间。这对我来说没有多大意义......
  • @Random:线程数在 50 左右(其他的被创建和销毁)
  • @nos: 线程之间不进行数据共享,只有父/主线程保持对运行线程的计数

标签: java multithreading memory-management thread-safety


【解决方案1】:

我在开发基于 GUI 的应用程序时遇到了类似类型的问题。

崩溃的原因

  • 创建线程池。使用 应用程序中的可用线程。 你不能创建无限线程 这会导致你的崩溃 应用
  • 可能是您正在创建新的 对象(或字符串)并存储 如果可能,数据使用相同的对象 赋值。如果数据很长 您可以存储在文件或数据库中。 而不是一直保存数据

【讨论】:

  • 我目前没有使用池化,但会尝试一下。另外,我应该直接停止线程还是让它们休眠并迭代地继续直到它们的工作结束?数据被存储在数据库中(这不是问题,因为它已经单独测试过)
  • 正如我所说,使用线程池不太可能避免内存泄漏,但它仍然是一个好主意。
【解决方案2】:

如果我正确理解了您的问题,那么您可以通过将旧线程值设置为 null 并执行 gc() 来绕过 OutOfMemory 错误

【讨论】:

  • 分析后,我已经解决了内存问题,但内存需求仍在不断增加(从最初的 20mb 到运行一天后的 ~250 mb)
  • 如果使用的内存继续扩大,你仍然有某种资源泄漏,内存,线程,句柄,一些东西正在被分配,当你完成它时永远不会被释放。
  • 这在很大程度上取决于内存的去向。内存是存储在短期还是长期堆存储中,还是(尽管不太可能)存储在 perm gen 中?如果您有 -Xmx 来表示 256mb 或其他一些较大的数字,它通常会在不进行任何剧烈垃圾收集的情况下增加,因此大量使用的内存可能是垃圾。
【解决方案3】:

您有内存泄漏。我建议您在内存不足时进行堆转储并分析它以查看泄漏的位置。

要自动触发堆转储,您可以使用选项

-XX:+HeapDumpOnOutOfMemoryError

也许

-XX:HeapDumpPath=/path/to/heap/dumps

如果你想要一个工作线程池,我建议你使用 ExecutorService 甚至是 ScheduledExecutorService 来定期执行任务。 (不过这不太可能是你的问题)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-07
    • 2015-03-31
    • 2013-03-26
    • 2019-02-22
    • 1970-01-01
    相关资源
    最近更新 更多