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