我正在处理OutOfMemory
中的WAS 6.1
以下异常。
Exception in thread "UnitHoldingsPolicySummary" java.lang.OutOfMemoryError: unable to create new native thread.
我已就此做了大量研究以防止这种情况发生。在谷歌搜索之后,我发现,当Native内存由于同时创建大量线程而耗尽时会发生这种情况。
现在,在分析了下面的日志之后,我们可以弄清楚,在应用程序内部,线程是明确创建的,我读到这是一个非常非常糟糕的做法。 (专家可以确认一下吗?)
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)
我更喜欢WAS管理,并且不具备Java中的Java和线程创建方面的知识。现在我需要与开发人员讨论这个问题,但在此之前我想100%确认我的发现是正确的,开发人员应该通过不明确地创建线程来纠正代码。
在将此问题归咎于代码之前,我需要在应用程序服务器端检查所有内容吗?
在solaris上,我正在触发命令pmap -x 9547|grep -i stack|wc -l
以检查在该实例时间上创建了多少个线程。我可以在“OutOfMemory”期间看到'问题,这个数字非常高。
请问您确认此命令是否是检查当前活动线程数的好方法?
使用我的最新发现编辑问题
此外,当出现此问题时,由于WAS没有从队列中获取消息,因此在同一个MQ队列中堆积起来。我可以在特定于应用程序的日志中看到以下错误。
Non recoverable Exception detected whilst connecting to queue manager or response queue
Underlying reason = MQJE001: Completion Code 2, Reason 2102
这个问题也可以与MQ相关吗?这又导致OutOfMemory
问题?
此致 拉胡
答案 0 :(得分:1)
为虚拟机实现线程系统有不同的可能性。两种极端形式是:
Thread
实例都在一个本机操作系统线程中进行管理。如果方法在native
调用内阻塞,则会导致此实现变得复杂,这可能会导致问题。最后,实现者需要引入 renegade threads 来保存本机锁以克服这些限制。 Thread
实例都由本机操作系统线程支持。对于绿色线程的命名限制,所有现代JVM实现(包括HotSpot)都选择后面的实现。这意味着操作系统需要为每个创建的线程保留一些内存。此外,创建此类线程需要一些运行时开销,因为它需要与底层操作系统直接交互。在某些时候,这些成本会累积,操作系统会拒绝创建新线程,以防止整个系统的稳定性。
因此应该将线程合并为resue。对象池通常被认为是不好的做法,因为许多程序员使用它来简化JVM的垃圾收集器。这不再有用,因为现代垃圾收集器已经过优化,可以处理短生物。今天,通过汇集对象,您可能会相反减慢系统速度。但是,如果对象由昂贵的本机资源(作为Thread
)支持,则仍建议使用池。查看ExecutorService
以了解在Java中汇集线程的规范方法。
通常,请考虑线程的上下文切换是昂贵的。您不应该为小任务创建新线程,这会降低您的应用程序速度。而是使您的应用程序更少并发。您只有一些核心可以在一开始就同时工作,创建比您的(非虚拟)核心更多的线程不会提高运行时性能。你是否实施了某种分而治之的算法?查看Java的ForkJoinPool
。
答案 1 :(得分:0)
是的,这是一种不好的做法。通常,您不管理Java EE服务器内的线程。通常"通常"我的意思是"在开发业务应用程序时#34;。
根据http://www.oracle.com/technetwork/java/restrictions-142267.html:
为什么不允许线程创建和管理?
EJB规范为EJB容器分配责任 用于管理线程。允许企业bean实例创建和 管理线程会干扰容器的控制能力 其组件'生命周期。线程管理不是一项业务 函数,它是一个实现细节,通常很复杂 和平台特定的。让容器管理线程减轻 处理线程问题的企业bean开发人员。 多线程应用程序仍然可行,但控制 多线程位于容器中,而不是在企业中 豆。
但是,我不认为您的日志表明正在明确创建线程。如果您想100%确定,请反编译部署并查看这些行中的代码。
另请看一下:
"java.lang.OutOfMemoryError : unable to create new native Thread"
而且:
https://plumbr.eu/outofmemoryerror/unable-to-create-new-native-thread
关于您的应用使用的线程数,我尝试使用JConsole或VisualVm等监控工具。