由于在java中显式创建线程而导致的问题

由于在java中显式创建线程而导致的问题,java,multithreading,websphere,out-of-memory,ibm-mq,Java,Multithreading,Websphere,Out Of Memory,Ibm Mq,我正在处理以下OutOfMemory异常was6.1 Exception in thread "UnitHoldingsPolicySummary" java.lang.OutOfMemoryError: unable to create new native thread. 我对此做了很多研究来防止这种情况。在谷歌搜索之后,我发现,当本机内存由于同时创建大量线程而耗尽时,就会发生这种情况 现在,在分析下面的日志之后,我们可以发现,在应用程序内部,线程是显式创建的,我认为这是一种非常糟糕的做法

我正在处理以下
OutOfMemory
异常
was6.1

Exception in thread "UnitHoldingsPolicySummary" java.lang.OutOfMemoryError: unable to create new native thread.
我对此做了很多研究来防止这种情况。在谷歌搜索之后,我发现,当本机内存由于同时创建大量线程而耗尽时,就会发生这种情况

现在,在分析下面的日志之后,我们可以发现,在应用程序内部,线程是显式创建的,我认为这是一种非常糟糕的做法。(专家们能确认一下吗?)

我更喜欢WAS管理,对Java和Java中的线程创建不太了解。现在我需要和开发人员讨论这一点,但在此之前,我想100%地确认我的发现是正确的,开发人员应该通过不显式地创建线程来纠正代码

在将此归咎于代码之前,我需要在应用服务器端检查哪些内容

在solaris上,我正在启动命令
pmap-x9547 | grep-istack | wc-l
,以检查在该时间实例上创建了多少线程。我可以看到,在“OutOfMemory”问题上,这个数字非常高

请确认此命令是否是检查当前活动线程数的好方法

用我的最新发现编辑问题

此外,当此问题发生时,同时MQ队列中的一个会堆积起来,因为WAS不会从队列中拾取消息。我可以在应用程序特定的日志中看到以下错误

连接到队列管理器或响应队列时检测到不可恢复的异常 基本原因=MQJE001:完成代码2,原因2102

这个问题是否也与MQ有关?这反过来会导致
OutOfMemory
问题

问候,,
拉胡尔是的,这是一个坏习惯。通常,您不会在JavaEE服务器内管理线程。我所说的“正常”是指“在开发业务应用程序时”

根据:

为什么不允许创建和管理线程

EJB规范将责任分配给EJB容器 用于管理线程。允许企业bean实例创建和 管理线程会干扰容器的控制能力 其组件的生命周期。线程管理不是一项业务 函数,这是一个实现细节,通常比较复杂 和平台特定。让容器管理线程可以减轻 处理线程问题的企业bean开发人员。 多线程应用程序仍然是可能的,但是 多线程位于容器中,而不是企业中 豆子

但是,我不认为您的日志显示线程是显式创建的。如果您想100%确定,请反编译可部署文件并查看这些行中的代码

还可以看看这个:

这是:


关于应用程序使用的线程数量,我会尝试使用JConsole或VisualVm之类的监控工具。

为虚拟机实现线程系统有不同的可能性。两种极端形式是:

  • 绿色线程:所有Java
    线程
    实例都在一个本机OS线程中管理。如果方法在
    native
    调用中阻塞,这可能会导致问题,这使得实现变得复杂。最后,实现者需要引入叛逆线程来持有本机锁以克服这些限制
  • 本机线程:每个Java
    线程
    实例都有一个本机OS线程作为后盾
  • 对于绿色线程的命名限制,所有现代JVM实现,包括HotSpot,都选择后面的实现。这意味着操作系统需要为每个创建的线程保留一些内存。此外,创建这样一个线程还需要一些运行时开销,因为它需要与底层操作系统直接交互。在某种程度上,这些成本会累积,操作系统会拒绝创建新线程,以防止整个系统的稳定性

    因此,线程应该为resue进行池化。对象池通常被认为是不好的做法,因为许多编程人员使用它来简化JVM的垃圾收集器。这不再有用,因为现代垃圾收集器已针对处理短生命对象进行了优化。今天,通过共享对象,您可能会反过来降低系统的速度。但是,如果对象由昂贵的本机资源(如
    线程
    )支持,则池仍然是推荐的做法。研究Java中的线程池的规范化方法


    一般来说,考虑线程的上下文切换是昂贵的。您不应该为小任务创建新线程,这会降低应用程序的速度。相反,要减少应用程序的并发性。首先,您只有多个可以并发工作的内核,创建比您的(非虚拟)内核更多的线程不会提高运行时性能。您是否正在实施某种分治算法?查看Java的。

    谢谢!我发布的日志是否确认线程是显式创建的?通常,您不会在JEE服务器内管理线程。你当然知道。不是所有的线程,但是你可以集成你自己的代码,当然可以为它的任务管理自己的线程。@Andres Nice,有类的。我相信你的答案是错误的,我解释了原因:你没有在JEE服务器中管理线程的说法是错误的。有了多个可用的处理器,编写多线程应用程序并将其部署到JEE容器中并不是问题。这不是问题所在,OP有。问题是线程是显式创建的,而不是使用池。解决方案是管理线程,而不是摆脱它们
    07/07/14 08:50:38:165 BST] 0000142c SystemErr     R Exception in thread "xxxxxx" java.lang.OutOfMemoryError: unable to create new native thread
            at java.lang.Thread.start0(Native Method)
            at java.lang.Thread.start(Thread.java:574)
            at com.fp.sv.controller.business.thread.xxxxxxxxxexecute(Unknown Source)
            at com.fp.sv.controller.business.thread.xxxxxxxxx.run(Unknown Source)
            at java.lang.Thread.run(Thread.java:595)