Uploaded image for project: 'Spring Integration'
  1. Spring Integration
  2. INT-4509

Memory leak in IntegrationFlowDefinition

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Critical
    • Resolution: Complete
    • Affects Version/s: 5.0.6
    • Fix Version/s: 5.0.7
    • Component/s: Core
    • Labels:

      Description

      It might just be me not doing things correctly, but I believe org.springframework.integration.dsl.IntegrationFlowDefinition.REFERENCED_REPLY_PRODUCERS holds on to instances forever, leading to a memory leak.

      I don't know how to come up with a proper test case apart from a very manual one – just run the code, fire up a profiler, and see instances of LeakyIntegrationFlowHandler piling up as flows get created and deleted.

      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.boot.SpringApplication;
      import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.integration.context.IntegrationContextUtils;
      import org.springframework.integration.dsl.IntegrationFlows;
      import org.springframework.integration.dsl.context.IntegrationFlowContext;
      import org.springframework.integration.dsl.context.IntegrationFlowRegistration;
      import org.springframework.messaging.Message;
      import org.springframework.scheduling.annotation.EnableScheduling;
      import org.springframework.scheduling.annotation.SchedulingConfigurer;
      import org.springframework.scheduling.config.ScheduledTaskRegistrar;
      
      import java.util.concurrent.TimeUnit;
      
      @Configuration
      @EnableAutoConfiguration
      @EnableScheduling
      public class SpringIntegrationTest implements SchedulingConfigurer {
      
          public static void main(String[] args) {
              SpringApplication.run(SpringIntegrationTest.class, args);
          }
      
          private final IntegrationFlowContext integrationFlowContext;
      
          @Autowired
          public SpringIntegrationTest(IntegrationFlowContext integrationFlowContext) {
              this.integrationFlowContext = integrationFlowContext;
          }
      
      
          @Override
          public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
              taskRegistrar.addFixedDelayTask(() -> {
                  IntegrationFlowRegistration registration = integrationFlowContext
                          .registration(
                                  IntegrationFlows
                                          .from(IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME)
                                          .handle(new LeakyIntegrationFlowHandler())
                                          .get()
                          )
                          .register();
      
                  System.out.println("Created flow");
      
                  try {
                      TimeUnit.SECONDS.sleep(1);
                  } catch (InterruptedException e) {
                      throw new RuntimeException(e);
                  }
      
                  registration.destroy();
      
                  System.out.println("Deleted flow");
              }, 1_000);
          }
      
          public static final class LeakyIntegrationFlowHandler {
      
              public void handle(Message<?> message) {
              }
          }
      }
      

        Attachments

          Activity

            People

            • Assignee:
              abilan Artem Bilan
              Reporter:
              timurstrekalov Timur Strekalov
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: