Hello Mark,

Please let me disagree with you. I have connected JVisualVM to Tomcat JVM,
run the test with 10,000 connections, performed several explicit GCs and
made a heap dump. All 10,000 WsSessions are in heap. They are referenced as
following:
this
 <- wsSession     - class:
org.apache.tomcat.websocket.server.WsHttpUpgradeHandler
  <- internalHttpUpgradeHandler     - class:
org.apache.coyote.http11.upgrade.UpgradeProcessorInternal
   <- val     - class: java.util.concurrent.ConcurrentHashMap$Node
    <- [12930]     - class: java.util.concurrent.ConcurrentHashMap$Node[]
     <- table     - class: java.util.concurrent.ConcurrentHashMap
      <- connections     - class:
org.apache.coyote.AbstractProtocol$ConnectionHandler
       <- handler     - class: org.apache.tomcat.util.net.NioEndpoint
        <- this$0 (Java frame)     - class:
org.apache.tomcat.util.net.NioEndpoint$Acceptor

Do you think it might be Tomcat configuration dependent? Please see my
server.xml below.

<?xml version='1.0' encoding='utf-8'?>
<Server port="8005" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
  <Listener className="org.apache.catalina.core.AprLifecycleListener"
SSLEngine="on" />
  <Listener
className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <Listener
className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener
className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
  <GlobalNamingResources>
    <Resource name="UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"
              description="User database that can be updated and saved"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="conf/tomcat-users.xml" />
  </GlobalNamingResources>
  <Service name="Catalina">
    <Connector port="8080"
protocol="org.apache.coyote.http11.Http11NioProtocol"
               asyncTimeout="20000"
               URIEncoding="utf-8"
               acceptorThreadCount="2"

 
compressableMimeType="text/html,text/xml,text/plain,text/x-json,application/javascript,application/json,text/css"
               compression="on"
               connectionTimeout="60000"
               maxThreads="1024"
               processorCache="512"
               redirectPort="8443" />
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
    <Engine name="Catalina" defaultHost="localhost">
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
      </Realm>
      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
        <Valve className="org.apache.catalina.valves.AccessLogValve"
directory="logs"
               prefix="localhost_access_log." suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot;
&quot;%{User-Agent}i&quot; %s %b %Dms" resolveHosts="false"/>
      </Host>
    </Engine>
  </Service>
</Server>

Thank you,
Kirill

On Tue, 30 Jul 2019 at 21:45, Mark Thomas <ma...@apache.org> wrote:

> On 30/07/2019 05:48, Kirill Ilyukhin wrote:
> > Hello Mark,
> >
> > Please see the test case and Tomcat JVM heap dump screenshot attached.
> > For sake of simplicity I do Thread.sleep() in client code instead of
> > reading bytes from server.
>
> That test case does not demonstrate a memory leak in either Tomcat 9.0.x
> nor Tomcat 8.5.x.
>
> There are some WsSession instances in memory at the end of the test but
> they are unreachable - i.e. eligible for GC.
>
> Mark
>
>
> > Test configuration is the following:
> >
> > Server version:        Apache Tomcat/8.5.3
> > Server built:          Jun 9 2016 11:16:29 UTC
> > Server number:         8.5.3.0
> > OS Name:               Mac OS X
> > OS Version:            10.14.5
> > Architecture:          x86_64
> > JVM Version:           1.8.0_112-b16
> > JVM Vendor:            Oracle Corporation
> > The APR based Apache Tomcat Native library which allows optimal
> > performance in production environments was not found on the
> > java.library.path: ...
> >
> > Thank you,
> > Kirill
> >
> > On Tue, 30 Jul 2019 at 02:15, Mark Thomas <ma...@apache.org
> > <mailto:ma...@apache.org>> wrote:
> >
> >     On 26/07/2019 10:33, Kirill Ilyukhin wrote:
> >     > Hello,
> >     >
> >     > When Tomcat receives WebSocket text message with invalid UTF-8, it
> >     closes
> >     > this connection with NOT_CONSISTENT reason. But after that some
> >     objects
> >     > (WsSession, UpgradeHandler, etc) stay in heap forever. They are
> >     referenced
> >     > from AbstractProtocol's connections map.
> >     >
> >     > This leak consistently happens with Tomcat 8.5.3 and 8.5.43, both
> >     on Mac OS
> >     > and Windows, with or without Tomcat native.
> >     >
> >     > I have created a very simple WebSocket Endpoint which does nothing
> >     except
> >     > logging its events and incoming messages, please see the code
> >     below. Also
> >     > you will need a WebSocket client which sends broken UTF-8 in text
> >     message
> >     > right after connecting to the server.
> >
> >     I can't repeat this with either 9.0.x nor 8.5.x. I've repeated the
> steps
> >     described above and checked the resulting state with a profiler. No
> >     references are retained to WsSession objects nor WsHttpUpgradeHandler
> >     objects.
> >
> >     You'll need to provide the simplest possible test case (single class
> >     client, simplest possible WAR) that demonstrates the issue.
> >
> >     Mark
> >
> >
> >     >
> >     > Thank you,
> >     > Kirill
> >     >
> >     > -----------------------
> >     > package com.example.wstest;
> >     >
> >     > import org.apache.log4j.Logger;
> >     > import javax.websocket.*;
> >     >
> >     > public class WSEndpoint extends Endpoint {
> >     >     private static final Logger logger =
> >     Logger.getLogger(WSEndpoint.class);
> >     >     private WSConnection connection;
> >     >
> >     >     @Override
> >     >     public void onOpen(Session session, EndpointConfig config) {
> >     >         connection = new WSConnection(session);
> >     >         logger.info <http://logger.info>("Opened WebSocket
> >     session-" + session.getId());
> >     >     }
> >     >
> >     >     @Override
> >     >     public void onClose(Session session, CloseReason closeReason) {
> >     >         logger.info <http://logger.info>("Closed WebSocket
> >     session-" + session.getId() + ",
> >     > reason: " + closeReason.getCloseCode() + " (" +
> >     > closeReason.getReasonPhrase() + ")");
> >     >         connection.destroy();
> >     >         connection = null;
> >     >     }
> >     >
> >     >     @Override
> >     >     public void onError(Session session, Throwable throwable) {
> >     >         logger.info <http://logger.info>("Error on WebSocket
> >     session-" + session.getId(),
> >     > throwable);
> >     >         connection.destroy();
> >     >         connection = null;
> >     >     }
> >     >
> >     >     static class WSConnection implements
> >     MessageHandler.Whole<String> {
> >     >         private final Session session;
> >     >
> >     >         WSConnection(Session session) {
> >     >             this.session = session;
> >     >             session.addMessageHandler(this);
> >     >         }
> >     >
> >     >         public void destroy() {
> >     >             session.removeMessageHandler(this);
> >     >         }
> >     >
> >     >         @Override
> >     >         public void onMessage(String message) {
> >     >             logger.info <http://logger.info>("Session-" +
> >     session.getId() + " onMessage(" +
> >     > message  +")");
> >     >         }
> >     >     }
> >     > }
> >     > -----------------------
> >     >
> >
> >
> >     ---------------------------------------------------------------------
> >     To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
> >     <mailto:users-unsubscr...@tomcat.apache.org>
> >     For additional commands, e-mail: users-h...@tomcat.apache.org
> >     <mailto:users-h...@tomcat.apache.org>
> >
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
> > For additional commands, e-mail: users-h...@tomcat.apache.org
> >
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: users-h...@tomcat.apache.org
>
>

Reply via email to