Repository: jooby-project/jooby
Issue: Memory leak in the jooby-netty implementation

In our project we use Jooby, and have more recently upgraded to version 2, currently running on the latest version 2.9.4.

I've spent a couple of days hunting down a memory leak within our application and have found out that the class:
`io.netty.handler.codec.DefaultHeaders$HeaderEntry` is causing some issue.

**How to recreate:**
Create an empty project with latest version of Jooby + Netty and Gradle. Run a POST-request to the running server, examine that the above mentioned class increases for every call (which is normal), but GC only manages to handle about 60% of it.

I have also created a project with Ktor + Netty, but this does NOT happen there, GC manages to clear what it should.

I have not looked into the implementation here, but hopefully you might now where to look?
It does seem to only apply to POST-requests, and it is quite hard to see it, we found it because we did not deploy for 4-5 days straight.

We have swapped to Jetty to test, and cannot see any memory leakage like this.

Please let me know if more information is required to solve this issue


Changed files:
modules/jooby-netty/src/main/java/io/jooby/internal/netty/HttpRawPostRequestDecoder.java
modules/jooby-netty/src/main/java/io/jooby/internal/netty/NettyHandler.java

diff --git a/modules/jooby-netty/src/main/java/io/jooby/internal/netty/HttpRawPostRequestDecoder.java b/modules/jooby-netty/src/main/java/io/jooby/internal/netty/HttpRawPostRequestDecoder.java
index 0834c7396..3df896914 100644
--- a/modules/jooby-netty/src/main/java/io/jooby/internal/netty/HttpRawPostRequestDecoder.java
+++ b/modules/jooby-netty/src/main/java/io/jooby/internal/netty/HttpRawPostRequestDecoder.java
@@ -6,8 +6,10 @@
 package io.jooby.internal.netty;
 
 import io.netty.handler.codec.http.HttpContent;
+import io.netty.handler.codec.http.HttpRequest;
 import io.netty.handler.codec.http.LastHttpContent;
 import io.netty.handler.codec.http.multipart.HttpData;
+import io.netty.handler.codec.http.multipart.HttpDataFactory;
 import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder;
 import io.netty.handler.codec.http.multipart.InterfaceHttpData;
 import io.netty.handler.codec.http.multipart.InterfaceHttpPostRequestDecoder;
@@ -18,10 +20,15 @@ import java.util.List;
 
 public class HttpRawPostRequestDecoder implements InterfaceHttpPostRequestDecoder {
 
+  private HttpRequest request;
+  private HttpDataFactory factory;
+
   private HttpData data;
 
-  public HttpRawPostRequestDecoder(HttpData data) {
-    this.data = data;
+  public HttpRawPostRequestDecoder(HttpDataFactory factory, HttpRequest request) {
+    this.factory = factory;
+    this.request = request;
+    this.data = factory.createAttribute(request, "body");
   }
 
   @Override public boolean isMultipart() {
@@ -69,12 +76,16 @@ public class HttpRawPostRequestDecoder implements InterfaceHttpPostRequestDecode
   }
 
   @Override public void destroy() {
+    cleanFiles();
+    removeHttpDataFromClean(data);
     data.delete();
   }
 
   @Override public void cleanFiles() {
+    factory.cleanRequestHttpData(request);
   }
 
   @Override public void removeHttpDataFromClean(InterfaceHttpData data) {
+    factory.removeHttpDataFromClean(request, data);
   }
 }
diff --git a/modules/jooby-netty/src/main/java/io/jooby/internal/netty/NettyHandler.java b/modules/jooby-netty/src/main/java/io/jooby/internal/netty/NettyHandler.java
index 82d180bd4..5e0922bf6 100644
--- a/modules/jooby-netty/src/main/java/io/jooby/internal/netty/NettyHandler.java
+++ b/modules/jooby-netty/src/main/java/io/jooby/internal/netty/NettyHandler.java
@@ -202,7 +202,7 @@ public class NettyHandler extends ChannelInboundHandlerAdapter {
         return new HttpPostStandardRequestDecoder(factory, request, StandardCharsets.UTF_8);
       }
     }
-    return new HttpRawPostRequestDecoder(factory.createAttribute(request, "body"));
+    return new HttpRawPostRequestDecoder(factory, request);
   }
 
   static String pathOnly(String uri) {