Tomcat 内存不足(无法创建新的本机线程)

2024-05-20

在给出错误 tomcat is exit(shutdow) 后,我的 1 个 tomcat 不断出现内存不足错误,其中部署了我的应用程序。

我查看了日志文件并发现了这个

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 中使用此连接器设置

<Connector port="80" protocol="HTTP/1.1" 
               connectionTimeout="10000" maxThreads="750" minSpareThreads="50" redirectPort="8443" />

有人可以建议我该怎么办吗?

线程转储

"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 <0x15c69398> (a com.microsoft.sqlserver.jdbc.TDSWriter)

我在 20 秒内进行了 4 个线程转储,发现此 tid 始终处于活动状态

我们能从这个转储中找到一些东西吗?

我从线程转储中得到这个,这表明死锁条件“被阻止”,因为我在相同状态下多次得到这个 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 可以创建的线程数量已达到一定限制。这可能是操作系统施加的限制,也可能是由于缺乏资源(如内存)。

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

如果与内存相关,您需要增加可用内存(添加更多物理内存或增加虚拟机上的内存)或降低每个线程的内存要求。要执行后面的操作,您可以使用以下命令更改线程堆栈大小-XssJVM 的参数。要找到理想的值,请从非常低的值开始,例如 128K 或 256K,然后查看是否出现任何 StackOverflow 异常。如果这样做,请增加直到它们消失。

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

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

看来您可能达到了 Tomcat 中线程池的限制。检查您的配置conf/server.xml。如果您使用执行器,请查找最大线程数 http://tomcat.apache.org/tomcat-6.0-doc/config/executor.html在那个元素上。如果没有,请寻找最大线程数 http://tomcat.apache.org/tomcat-6.0-doc/config/http.html在连接器元素上。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Tomcat 内存不足(无法创建新的本机线程) 的相关文章

随机推荐