有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

我的tomcat中有一个在给定错误tomcat退出(shutdow)后部署应用程序的地方不断出现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

我正在服务器中使用此连接器设置。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)

共 (1) 个答案

  1. # 1 楼答案

    java.lang.OutOfMemoryError: unable to create new native thread

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

    如果这是操作系统强加的限制,那么您可以提高它,前提是您具有该级别的系统访问权限

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

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

    INFO: Maximum number of threads (750) created for connector with address null and port 80

    在Tomcat中,您的线程池似乎达到了一个极限。检查conf/server.xml中的配置。如果您使用的是执行器,请在该元素上查找maxThreads。如果不是,请在连接器元素上查找maxThreads