太多等待线程导致java 8中websocket客户端中的java堆转储

太多等待线程导致java 8中websocket客户端中的java堆转储,java,Java,今天我的java应用程序堆转储,我使用visualVM从服务器分析复制转储文件,日志如下所示: "WebSocketClient-SecureIO-1" daemon prio=5 tid=888 WAITING at sun.misc.Unsafe.park(Native Method) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) at java.util.

今天我的java应用程序堆转储,我使用visualVM从服务器分析复制转储文件,日志如下所示:

"WebSocketClient-SecureIO-1" daemon prio=5 tid=888 WAITING
    at sun.misc.Unsafe.park(Native Method)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:997)
       local variable: java.util.concurrent.locks.AbstractQueuedSynchronizer$Node#184
       local variable: java.util.concurrent.locks.AbstractQueuedSynchronizer$Node#185
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1304)
       local variable: java.util.concurrent.CountDownLatch$Sync#36
    at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:231)
       local variable: java.util.concurrent.CountDownLatch#35
    at sun.nio.ch.PendingFuture.get(PendingFuture.java:180)
    at org.apache.tomcat.websocket.AsyncChannelWrapperSecure$ReadTask.run(AsyncChannelWrapperSecure.java:269)
       local variable: sun.nio.ch.PendingFuture#47
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
       local variable: java.util.concurrent.ThreadPoolExecutor#1
       local variable: org.apache.tomcat.websocket.AsyncChannelWrapperSecure$ReadTask#6
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
       local variable: java.util.concurrent.ThreadPoolExecutor$Worker#1
    at java.lang.Thread.run(Thread.java:748)

"WebSocketClient-SecureIO-2" daemon prio=5 tid=889 WAITING
    at sun.misc.Unsafe.park(Native Method)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
       local variable: java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject#5
       local variable: java.util.concurrent.locks.AbstractQueuedSynchronizer$Node#114
    at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
       local variable: java.util.concurrent.LinkedBlockingQueue#1
       local variable: java.util.concurrent.atomic.AtomicInteger#56
       local variable: java.util.concurrent.locks.ReentrantLock#9
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
       local variable: java.util.concurrent.ThreadPoolExecutor$Worker#2
    at java.lang.Thread.run(Thread.java:748)

"pool-87-thread-1" prio=5 tid=890 TIMED_WAITING
    at sun.misc.Unsafe.park(Native Method)
    at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
       local variable: java.util.concurrent.locks.AbstractQueuedSynchronizer$Node#183
       local variable: java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject#558
    at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093)
       local variable: java.util.concurrent.locks.ReentrantLock#3654
    at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
       local variable: java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue#1
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
       local variable: java.util.concurrent.ScheduledThreadPoolExecutor#129
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
       local variable: java.util.concurrent.ThreadPoolExecutor$Worker#3
    at java.lang.Thread.run(Thread.java:748)
似乎太多线程(可能数千个)一直在等待,我的内存现在配置为500MB,我现在不知道为什么会发生这种情况。这是我的websocket连接代码:

 public WebsocketClientEndpoint robotNewConnect(Long roomTypeId, String token, String userMark) {
        WebsocketClientEndpoint clientEndPoint = null;
        String websocketConnUrl = websocketUrl + "?token=" + token + "&roomTypeId=" + roomTypeId + "&robotFlag=1";
        try {
            String appMark = SessionUtil.getThreadLocal("appMark");
           
            clientEndPoint = new WebsocketClientEndpoint(new URI(websocketConnUrl));
            clientEndPoint.userSession.getUserProperties().put("userIdentity", userMark + "-" + appMark + "-" + roomTypeId);
            clientEndPoint.addMessageHandler(message -> {
                log.info("addMessageHandler:", message);
            });
        } catch (Exception e) {
            log.error("Websocket", e);
        }
        return clientEndPoint;
    }
我正在上网,试图增强记忆力,但问题仍然没有解决。什么可能导致此问题?我应该如何解决此问题

我所尝试的:

  • 我遵循
    tomcat-embed-websocket-9.0.30
    的源代码,其中class
    WebsocketClientEndpoint
    属于。连接成功,但卡在这行代码上:
  • WsFrameClient WsFrameClient=新的WsFrameClient(响应、通道、wsSession、转换)

    我走进课堂,发现代码卡在死锁代码中:

    private void doResumeProcessing(boolean checkOpenOnError) {
                while (true) {
                    switch (getReadState()) {
                    case PROCESSING:
                        if (!changeReadState(ReadState.PROCESSING, ReadState.WAITING)) {
                            continue;
                        }
                        resumeProcessing(checkOpenOnError);
                        return;
                    case SUSPENDING_PROCESS:
                        if (!changeReadState(ReadState.SUSPENDING_PROCESS, ReadState.SUSPENDED)) {
                            continue;
                        }
                        return;
                    default:
                        throw new IllegalStateException(
                                sm.getString("wsFrame.illegalReadState", getReadState()));
                    }
                }
            }
    
    读取状态
    getReadState
    总是
    PROCESSING
    ,代码永远循环,这就是转储文件中有这么多等待线程的原因


    但是现在我不知道为什么读取状态是
    处理
    ,以及如何解决它?有人能帮我吗?

    那么到底是什么问题?创建的线程太多?我不明白为什么增加内存会减少创建的线程数量假设你在Linux中,你能检查netstat-anp | grep WAIT并附加它吗?也许你的后端太慢了?顺便说一下,在问题中,您提到了堆转储,但您附加了线程转储。你能给我们看一些关于堆转储的快照吗?您是否面临内存不足问题?有时日志显示
    2020-08-12 19:37:49.519错误1---[ool-10-thread-1]o.s.s.s.TaskUtils$LoggingErrorHandler:计划任务中发生意外错误。java.lang.OutOfMemoryError:java堆空间
    ,有一段时间整个应用程序dump@rcastellcastellso到底是什么问题?创建的线程太多?我不明白为什么增加内存会减少创建的线程数量假设你在Linux中,你能检查netstat-anp | grep WAIT并附加它吗?也许你的后端太慢了?顺便说一下,在问题中,您提到了堆转储,但您附加了线程转储。你能给我们看一些关于堆转储的快照吗?您是否面临内存不足问题?有时日志显示
    2020-08-12 19:37:49.519错误1---[ool-10-thread-1]o.s.s.s.TaskUtils$LoggingErrorHandler:计划任务中发生意外错误。java.lang.OutOfMemoryError:java堆空间
    ,有一段时间整个应用程序dump@rcastellcastell