我正在处理下面的OutOfMemory
异常中的AS6.1
。
Exception in thread "UnitHoldingsPolicySummary" java.lang.OutOfMemoryError: unable to create new native thread.
我对此做了很多研究来防止这种情况。在谷歌搜索之后,我发现,当本机内存由于同时创建大量线程而耗尽时,就会发生这种情况。
现在,在分析了下面的日志之后,我们可以发现,在应用程序内部,线程是明确创建的,这是一个非常非常糟糕的做法。(专家能否证实这一点?)
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-x9547 | grep-istack | wc-l
,以检查在该时间实例上创建了多少线程。我可以看到,在“OutOfMemory”问题上,这个数字非常高。
请确认此命令是否是检查当前活动线程数的好方法?
用我的最新发现编辑这个问题
此外,当此问题发生时,同时MQ队列中的一个会堆积起来,因为WAS不会从队列中拾取消息。我可以在应用程序特定的日志中看到以下错误。
连接到队列管理器或响应队列时检测到不可恢复的异常,基本原因=MQJE001:完成代码2,原因2102
这个问题是否也与MQ有关?这反过来又会导致OutOfMemory
问题?
问候你,拉胡尔
是的,这是个坏习惯。通常,您不会在JavaEE服务器内管理线程。我所说的“正常”是指“在开发业务应用程序时”。
根据http://www.oracle.com/technetwork/java/restrictions-142267.html:
为什么不允许线程创建和管理?
EJB规范将管理线程的责任分配给EJB容器。允许企业bean实例创建和管理线程会干扰容器控制其组件生命周期的能力。线程管理不是一个业务功能,它是一个实现细节,通常是复杂的和特定于平台的。让容器管理线程可以减轻企业bean开发人员处理线程问题的负担。多线程应用程序仍然是可能的,但多线程控制位于容器中,而不是企业bean中。
但是,我不认为您的日志显示线程是显式创建的。如果您想100%确定,请反编译可部署文件并查看这些行中的代码。
还可以看看这个:
"java.lang.OutOfMemoryError:无法创建新的本机线程"
这是:
https://plumbr.eu/outofmemoryerror/unable-to-create-new-native-thread
关于应用程序使用的线程数量,我会尝试使用JConsole或VisualVm之类的监控工具。
为虚拟机实现线程系统有不同的可能性。两种极端形式是:
Thread
实例都在一个本机OS线程中进行管理。如果方法在本机
调用中阻塞,这可能会导致问题,这使得实现变得复杂。最后,实现者需要引入用于保持本机锁的变节线程来克服这些限制。Thread
实例都由一个本地OS线程支持。对于绿色线程的命名限制,所有现代JVM实现,包括HotSpot,都选择后面的实现。这意味着操作系统需要为每个创建的线程保留一些内存。此外,创建这样一个线程会有一些运行时开销,因为它需要与底层操作系统直接交互。在某个时候,这些成本会累积起来,操作系统会拒绝创建新线程来阻止整个系统的稳定性。
因此,线程应该为resue进行池化。对象池通常被认为是不好的做法,因为许多编程人员使用它来简化JVM的垃圾收集器。这不再有用,因为现代垃圾收集器已针对处理短生命对象进行了优化。今天,通过共享对象,您可能会反过来降低系统的速度。但是,如果对象由昂贵的本机资源(如线程
)支持,则池仍然是推荐的做法。查看ExecutorService
,了解Java中共享线程的规范方法。
一般来说,考虑线程的上下文切换是昂贵的。您不应该为小任务创建新线程,这会降低应用程序的速度。相反,要减少应用程序的并发性。首先,您只有多个可以并发工作的内核,创建比您的(非虚拟)内核更多的线程不会提高运行时性能。您是否正在实施某种分治算法?查看Java的ForkJoinPool
。
问题内容: 我有两个加载同一个类的ClassLoader。因此,显然这些不能互相投射。但是我需要访问在其他ClassLoader中创建的对象。 我可以访问两个ClassLoader。如何在其他课程中使用该对象?我不需要强制转换对象以匹配当前的ClassLoader。 但是问题在于返回的对象的类型为。因此,我必须放弃该对象才能访问某些方法。我怎样才能做到这一点?像下面这样的普通类型转换会导致Clas
主要内容:1 创建线程的两种方式,2 Thread类,3 Runnable接口,4 如何启动线程,5 创建线程的例子1 创建线程的两种方式 有两种创建线程的方法: 通过继承Thread类 通过实现Runnable接口。 2 Thread类 Thread类提供了构造方法和方法来创建和执行线程。Thread类继承Object类并实现了Runnable接口。 Thread类的构造方法有: Thread() Thread(String name) Thread(Runnable r) Thread(Ru
问题内容: 我有一个经典的Java EE系统,具有JSF的Web层,用于BL的EJB 3和用于对DB2数据库进行数据访问的Hibernate 3。我在以下情况下苦苦挣扎:用户将启动一个过程,该过程涉及从数据库中检索大型数据集。检索过程花费一些时间,因此用户不会立即收到响应,变得不耐烦,并打开新的浏览器并再次启动检索,有时是多次。EJB容器显然没有意识到第一次检索不再相关的事实,并且当数据库返回结果
我们在项目中使用了spring integration(spring-integration-core:jar:5.0.14.release)。我们的应用程序在JBoss7 EAP中运行良好。现在我们希望使它与WebSphere9应用服务器兼容。当我们在WebSphere9中部署应用程序并试图访问它时,我们会遇到以下错误。int-xml:xslt-transformer似乎存在一些问题。是否有不兼
问题内容: 在此 coderanch链接上,我发现以下注释将给编译器错误:- 原因是,Unicode序列直接由其对应的实际字符替换。由于’\ u000a’对应于newLine字符,因此将newLine放置在找到’\ u000a’的位置。 我的问题是,“由于注释,还有其他方式导致编译错误吗?” 问题答案: 如果在注释()中定义了不推荐使用的函数,并且设置了使用不推荐使用的方法时编译器抛出错误(至少可
假设我有三节课: 我的问题是: 在这种情况下创建了多少个对象? 如果创建了一个对象,那么Super()如何在内部调用父类构造函数?