Out Of Memory Tomcat(无法创建新的本机线程)

在给出错误tomcat退出(关闭)之后,我正在为我的tomcat中的一个部署我的应用程序而持续outofmemory错误。

我拿了日志文件,发现了这个

SEVERE: Error allocating socket processor java.lang.OutOfMemoryError: unable to create new native thread at java.lang.Thread.start0(Native Method) at java.lang.Thread.start(Thread.java:597) at org.apache.tomcat.util.net.JIoEndpoint$Worker.start(JIoEndpoint.java:513) at org.apache.tomcat.util.net.JIoEndpoint.newWorkerThread(JIoEndpoint.java:744) at org.apache.tomcat.util.net.JIoEndpoint.createWorkerThread(JIoEndpoint.java:723) at org.apache.tomcat.util.net.JIoEndpoint.getWorkerThread(JIoEndpoint.java:757) at org.apache.tomcat.util.net.JIoEndpoint.processSocket(JIoEndpoint.java:789) at org.apache.tomcat.util.net.JIoEndpoint$Acceptor.run(JIoEndpoint.java:355) at java.lang.Thread.run(Thread.java:619) 18 Feb, 2015 5:43:30 PM org.apache.tomcat.util.net.JIoEndpoint createWorkerThread INFO: Maximum number of threads (750) created for connector with address null and port 80 

我在server.xml中使用此连接器设置

  

谁能告诉我我该怎么办?

线程转储

 "http-80-123" daemon prio=6 tid=0x5f5e7400 nid=0xcfc runnable [0x619be000..0x619bf9e8] java.lang.Thread.State: RUNNABLE at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.read(SocketInputStream.java:129) at com.microsoft.sqlserver.jdbc.DBComms.receive(Unknown Source) at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(Unknown Source) at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PreparedStatementExecutionRequest.executeStatement(Unknown Source) at com.microsoft.sqlserver.jdbc.CancelableRequest.execute(Unknown Source) at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeRequest(Unknown Source) - locked  (a com.microsoft.sqlserver.jdbc.TDSWriter) 

我在20秒的时间内完成了4个线程转储,并且发现这个tid一直存在

我们能找到这个转储的东西吗?

我从线程转储得到这个,这表明死锁条件’BLOCKED’,因为我得到这几次80-90相同的状态

 "http-80-342" daemon prio=6 tid=0x5c0d7c00 nid=0x1d0c waiting for monitor entry [0x6ee0e000..0x6ee0fce8] java.lang.Thread.State: BLOCKED (on object monitor) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:247) at java.sql.DriverManager.getCallerClass(DriverManager.java:477) at java.sql.DriverManager.getConnection(DriverManager.java:576) at java.sql.DriverManager.getConnection(DriverManager.java:185) at t4u.common.DBConnection.getConnectionToDB(DBConnection.java:32) at t4u.functions.CommonFunctions.getProcessID(CommonFunctions.java:1465) 

java.lang.OutOfMemoryError:无法创建新的本机线程

这意味着您已经对JVM可以创建的线程数量设置了一些限制。 这可能是操作系统施加的限制,也可能是由于缺乏资源(如内存)。

如果它是操作系统强加的限制,您可以提高它,假设您具有该系统的访问级别。

如果它与内存相关,则需要增加可用内存(在VM上添加更多物理内存或增加内存)或降低每个线程的内存要求。 要执行此操作,可以使用-Xss参数将线程堆栈大小更改为JVM。 要找到理想值,请从128K或256K开始,看看是否有任何StackOverflowexception。 如果你这样做,请增加直到它们消失。

另一种可能性是使用不同的Connector实现。 您还没有说明您当前正在使用哪一个,但BIO(阻塞IO)连接器每个请求消耗一个线程。 根据您的应用程序正在执行的操作,如果使用NIO或APR连接器,您可能会看到更好的线程利用率(即处理相同数量的请求所需的线程更少)。 这里没有足够的信息让我说出这种或那种方式,但你可能想用你的应用程序测试它,看看所需的线程数是否下降。

INFO:为地址为null和端口80的连接器创建的最大线程数(750)

这看起来可能会对Tomcat中的线程池造成限制。 检查conf/server.xml配置。 如果您正在使用Executor,请在该元素上查找maxThreads 。 如果没有,请在Connector元素上查找maxThreads 。