Java线程数量随时间增长的原因

Java线程数量随时间增长的原因,java,multithreading,jvm,profiler,java-threads,Java,Multithreading,Jvm,Profiler,Java Threads,我有一个独立的Java控制台程序,它在生产中使用大约80-170个线程(160是平均负载下的典型数字)。项目中的某些代码被替换,虽然功能良好,但在启动程序后线程数不断增加。 当虚拟机几乎崩溃时,我发现了这个问题。然后它有30000个线程 我想在生产环境中找到这种行为的原因,因此如果有任何有用的工具,它必须是命令行程序,或者应该能够从远程主机运行 我用“ps-huH p | wc-l”命令和VisualVm程序检查了它。不幸的是,VisualVm remote只提供线程编号的信息,“线程”选项卡未

我有一个独立的Java控制台程序,它在生产中使用大约80-170个线程(160是平均负载下的典型数字)。项目中的某些代码被替换,虽然功能良好,但在启动程序后线程数不断增加。 当虚拟机几乎崩溃时,我发现了这个问题。然后它有30000个线程

我想在生产环境中找到这种行为的原因,因此如果有任何有用的工具,它必须是命令行程序,或者应该能够从远程主机运行

我用“ps-huH p | wc-l”命令和VisualVm程序检查了它。不幸的是,VisualVm remote只提供线程编号的信息,“线程”选项卡未激活

我试图从jstack命令中获得有用的信息,但是我找不到创建etc的新线程是什么

"Timer-459" #1864 daemon prio=10 os_prio=0 tid=0x0bb6c400 nid=0x3c4f in Object.wait() [0x2a980000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    at java.lang.Object.wait(Object.java:502)
    at java.util.TimerThread.mainLoop(Timer.java:526)
    - locked <0x4d18bc80> (a java.util.TaskQueue)
    at java.util.TimerThread.run(Timer.java:505)
“Timer-459”#1864守护进程prio=10 os_prio=0 tid=0x0bb6c400 nid=0x3c4f在Object.wait()中[0x2a980000]
java.lang.Thread.State:正在等待(在对象监视器上)
在java.lang.Object.wait(本机方法)
在java.lang.Object.wait(Object.java:502)
位于java.util.TimerThread.mainLoop(Timer.java:526)
-锁定(java.util.TaskQueue)
在java.util.TimerThread.run(Timer.java:505)

“pool-133-thread-2”#1877 prio=5 os_prio=0 tid=0x42a2c400 nid=0x3e5e等待条件[0x2b118000]
java.lang.Thread.State:等待(停车)
在sun.misc.Unsafe.park(本机方法)
-停车等待(java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
位于java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
位于java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
位于java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
位于java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
位于java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
位于java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
运行(Thread.java:748)
我不明白他们是什么

你能帮我找出是什么代码一次又一次地创建新线程吗?有什么好工具吗


谢谢大家!

我想说
jstack
是完成这类任务的正确工具。通过堆栈跟踪和源代码,您可以了解线程的本质。
例如,java.util.TimerThread.mainLoop(Timer.java:526)中的
表示您的代码使用
Timer
类,其线程正在等待下一个调度
java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
表示您使用了一个
ExecutorService
实现,其工作线程正在等待下一个任务。尝试分析有多少线程池线程处于活动状态以及原因,它们可能是问题的根源。

中的“线程监视器”视图可以向您显示只要CPU记录处于活动状态,创建任何线程的堆栈跟踪


免责声明:我的公司开发了JProfiler。

有用的工具:调试器。它将显示您的所有线程,并可以挂起它们,以便您可以查看调用堆栈,并逐步查看代码以了解它在做什么。如果不想连接调试器,只需获取。--如果你知道新线程在做什么,你应该能够首先弄清楚为什么要启动它们。它是一个大型的、单片的、多线程的应用程序,很难调试。关于线程转储,我更新了我的描述。我阅读了附件中的答案,我认为它不在这里。问题不在于我如何进行线程转储,而在于我如何找到谁创建了上述线程,或者我应该识别什么模式,或者只是在过去的x秒内创建了哪些线程。谢谢!我自己解决了这个问题——这是编程错误。但如果没有它,我就不会认识杰克罗菲勒。我在自己的电脑上试过,它认为这是一个伟大的东西!很好,您正在开发这样的产品。使用jstack,我发现了问题。日志显示了timertasks创建的许多线程。很高兴听到:)
"pool-133-thread-2" #1877 prio=5 os_prio=0 tid=0x42a2c400 nid=0x3e5e waiting on condition [0x2b118000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x4d18ae80> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
    at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)