Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memory leak in HttpRequestExecutingMessageHandler [INT-3698] #7658

Closed
spring-operator opened this issue Apr 12, 2015 · 2 comments
Closed

Memory leak in HttpRequestExecutingMessageHandler [INT-3698] #7658

spring-operator opened this issue Apr 12, 2015 · 2 comments

Comments

@spring-operator
Copy link
Contributor

Roland Csupor opened INT-3698 and commented

I have many spring contexts, one parent and this has many child contexts. I use the outbound-gateway in the child contexts.

The HttpRequestExecutingMessageHandler creates and adds two converters to the conversionService in the doInit method:

	protected void doInit() {
		this.evaluationContext = ExpressionUtils.createStandardEvaluationContext(this.getBeanFactory());

		ConversionService conversionService = this.getConversionService();
		if (conversionService == null){
			conversionService = new GenericConversionService();
		}
		if (conversionService instanceof ConverterRegistry){
			ConverterRegistry converterRegistry =
					(ConverterRegistry) conversionService;

			converterRegistry.addConverter(new ClassToStringConverter());
			converterRegistry.addConverter(new ObjectToStringConverter());

			this.evaluationContext.setTypeConverter(new StandardTypeConverter(conversionService));
		}
		else {
			logger.warn("ConversionService is not an instance of ConverterRegistry therefore" +
					"ClassToStringConverter and ObjectToStringConverter will not be registered");
		}
	}

These two classes is are inner classes, not statics.

If I have an integration bean in any of my parent processes, the getConversionService method returns the same conversionService for all of my child contexts from that parent context. This results if I close my child context, the instance of HttpRequestExecutingMessageHandler remains in the heap because the converter classes are not statics but inner classes.

It would be good if these two classes be statics, not inner classes. In this case after the context close, the HttpRequestExecutingMessageHandler would release from the memory.

The other idea that it would be good in the doInit method if the converter registration placed after a condition:

if (!conversionService.canConvert(Class.class, String.class)) {
    converterRegistry.addConverter(new ClassToStringConverter());
}
if (!conversionService.canConvert(Object.class, String.class)) {
    converterRegistry.addConverter(new ObjectToStringConverter());
}

Affects: 4.1.3

Referenced from: pull request #1420

Backported to: 4.0.8

@spring-operator
Copy link
Contributor Author

Roland Csupor commented

I can add a test case:

public class MemoryLeakTest {

	@Test
	public void test() throws InterruptedException {
		final ClassPathXmlApplicationContext parent = new ClassPathXmlApplicationContext("baseContext.xml");
		final String[] childResources = new String[] { "additionalContext.xml" };

		final ClassPathXmlApplicationContext child = new ClassPathXmlApplicationContext(childResources, parent);

		child.stop();
		child.close();

		System.out.println("Child context closed.");

		Thread.sleep(600000);
	}
}

baseContext.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:int="http://www.springframework.org/schema/integration"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-4.1.xsd">

	<int:channel id="dummy" />

</beans>

additionalContext.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:int="http://www.springframework.org/schema/integration"
	xmlns:int-http="http://www.springframework.org/schema/integration/http"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-4.1.xsd
		http://www.springframework.org/schema/integration/http http://www.springframework.org/schema/integration/http/spring-integration-http-4.1.xsd">

	<int:chain id="testChain" input-channel="testChannel">

		<int-http:outbound-gateway url="http://twitter.com" />

	</int:chain>

</beans>

@spring-operator
Copy link
Contributor Author

Gary Russell commented

Merged and cherry-picked. Deferring backport to 3.0.x unless some user reports it and can't upgrade.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants