[ 
https://issues.apache.org/jira/browse/WICKET-6944?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17472501#comment-17472501
 ] 

Martin Tzvetanov Grigorov commented on WICKET-6944:
---------------------------------------------------

How about this change:

 
{code:java}
diff --git 
wicket-native-websocket/wicket-native-websocket-javax/src/main/java/org/apache/wicket/protocol/ws/javax/WicketEndpoint.java
 
wicket-native-websocket/wicket-native-websocket-javax/src/main/java/org/apache/wicket/protocol/ws/javax/WicketEndpoint.java
index b5b0b2b922..eb2d7416d6 100644
--- 
wicket-native-websocket/wicket-native-websocket-javax/src/main/java/org/apache/wicket/protocol/ws/javax/WicketEndpoint.java
+++ 
wicket-native-websocket/wicket-native-websocket-javax/src/main/java/org/apache/wicket/protocol/ws/javax/WicketEndpoint.java
@@ -20,6 +20,8 @@ import java.io.EOFException;
 import java.io.IOException;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import jakarta.websocket.CloseReason;
@@ -49,6 +51,7 @@ public class WicketEndpoint extends Endpoint
        private static final String WICKET_APP_PARAM_NAME = "wicket-app-name";
 
        private final AtomicBoolean applicationDestroyed = new 
AtomicBoolean(false);
+       private final Set<String> registeredListeners = 
ConcurrentHashMap.newKeySet();
 
        private JavaxWebSocketProcessor javaxWebSocketProcessor;
 
@@ -58,7 +61,9 @@ public class WicketEndpoint extends Endpoint
                String appName = getApplicationName(session);
 
                WebApplication app = (WebApplication) 
WebApplication.get(appName);
-               app.getApplicationListeners().add(new 
ApplicationListener(applicationDestroyed));
+               if (registeredListeners.add(appName)) {
+                       app.getApplicationListeners().add(new 
ApplicationListener(applicationDestroyed));
+               }
 
                try
                {
 {code}
 

> Memory leak in WicketEndpoint
> -----------------------------
>
>                 Key: WICKET-6944
>                 URL: https://issues.apache.org/jira/browse/WICKET-6944
>             Project: Wicket
>          Issue Type: Bug
>          Components: wicket-native-websocket
>    Affects Versions: 9.7.0
>            Reporter: Thomas Heigl
>            Assignee: Thomas Heigl
>            Priority: Major
>         Attachments: image-2022-01-10-18-52-42-193.png
>
>
> Our application OOMed yesterday after about 2-3 weeks of continuous uptime. 
> We normally deploy every other day, so we never noticed this issue before.
> The heap dump identified the possible culprit as 
> {{{}WicketEndpoint$ApplicationListener{}}}:
> !image-2022-01-10-18-52-42-193.png!
> Every new websocket connection registers a new instance of this application 
> listener and after a while we ended up with millions of these listeners:
> {code:java}
> @Override
> public void onOpen(Session session, EndpointConfig endpointConfig)
> {
>     String appName = getApplicationName(session);
>     WebApplication app = (WebApplication) WebApplication.get(appName);
>     app.getApplicationListeners().add(new 
> ApplicationListener(applicationDestroyed));
>     try
>     {
>         ThreadContext.setApplication(app);
>         javaxWebSocketProcessor = new JavaxWebSocketProcessor(session, app, 
> endpointConfig);
>     }
>     finally
>     {
>         ThreadContext.detach();
>     }
> }
> {code}
> Instead of creating a new listener for every connection, the listener should 
> be a singleton.



--
This message was sent by Atlassian Jira
(v8.20.1#820001)

Reply via email to