如何解读 Eclipse Memory Analyzer(骆驼路线中的内存泄漏)

How to interpret Eclipse Memory Analizer (memory leaks in a camel route)

我运行在JBoss保险丝有几条骆驼路线(大约100条)。最近我遇到了 OutOfMemoryError: Java heap space 所以我决定使用 Eclipse Memory Analyzer Tool 来寻找泄漏。

报告显示了几个嫌疑人,但最大的一个是:

11.539 instances of "org.apache.http.impl.conn.PoolingHttpClientConnectionManager", loaded by "org.apache.felix.framework.BundleWiringImpl$BundleClassLoaderJava5 @ 0xd16558b8" occupy 443.624.920 (63,87%) bytes.

与其他泄漏问题不同,此案例的详细报告很小,只有 4 行:

class java.lang.Thread @ 0xd0a9c0c8
\class org.apache.camel.component.jms.DefaultJmsMessageListenerContainer @ 0xd367ee58 .\class org.apache.camel.component.jms.JmsQueueEndpoint @ 0xd36750d8
..\class org.apache.camel.blueprint.BlueprintCamelContext @ 0xd33bcd50

好像是http连接出了问题,但我真的不知道。

我在 pollEnrichers 中使用 http 组件是这样的:

from(URI_COLA_ENTRADA_STEP)
.pollEnrich().simple("{{URL_CORRELATIVO}}?ruta=STEP", String.class).aggregationStrategy(new EstrategiaCorrelativo()).cacheSize(1).timeout(10000).aggregateOnException(true)
.to(URI_TOPIC_ARTICULOS);

或在处理器中使用 ProducerTemplate

final String URL = exchange.getContext().resolvePropertyPlaceholders("{{URL_PAGO}}");
ProducerTemplate producer = exchange.getContext().createProducerTemplate();
String response = producer.requestBody(URL, "", String.class);
producer.stop();

因此,如您所见,我没有做任何太复杂的事情。

可能导致问题的原因是什么?

好的...我解决了问题。这是骆驼参数和http参数之间的事情。

第一:其实我是这样使用http4组件的:

String URL = exchange.getContext().resolvePropertyPlaceholders("{{URL_PAGO}}");

String PARAMS = "?param1=" + value1 + "&param2=" + value2;

ProducerTemplate producer = exchange.getContext().createProducerTemplate();
String response = producer.requestBody(URL + PARAMS, "", String.class);
producer.stop();

我这样做是因为文档说:

The camel-http4 producer supports URI parameters to be sent to the HTTP server. The URI parameters can either be set directly on the endpoint URI or as a header with the key Exchange.HTTP_QUERY on the message:

但是...如果value1and/orvalue2改变,camel会用URL + PARAMS 创建一个新端点。因此,如果我使用该代码一百万次,它将创建一百万个包含所有内容(headers、缓存等)的 http4 端点。

为了避免这种情况,我使用 Exchange.HTTP_QUERY header:

String URL = exchange.getContext().resolvePropertyPlaceholders("{{URL_PAGO}}");

String PARAMS = "param1=" + value1 + "&param2=" + value2;
Map<String,Object> headers = new HashMap<String,Object>();
headers.put(Exchange.HTTP_QUERY, PARAMS);

ProducerTemplate producer = exchange.getContext().createProducerTemplate();
String response = producer.requestBody(URL, "",headers, String.class);
producer.stop();

使用这种方法,camel 只创建了 1 个 http4 端点。

关于这一点,我认为文档应该更详细。

再见。