You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@camel.apache.org by "Claus Ibsen (Jira)" <ji...@apache.org> on 2023/10/24 07:57:00 UTC
[jira] [Assigned] (CAMEL-20035) Program terminates with OutOfMemoryError
[ https://issues.apache.org/jira/browse/CAMEL-20035?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Claus Ibsen reassigned CAMEL-20035:
-----------------------------------
Assignee: Claus Ibsen
> Program terminates with OutOfMemoryError
> ----------------------------------------
>
> Key: CAMEL-20035
> URL: https://issues.apache.org/jira/browse/CAMEL-20035
> Project: Camel
> Issue Type: Bug
> Components: camel-core
> Affects Versions: 4.0.0
> Reporter: Marco Bungart
> Assignee: Claus Ibsen
> Priority: Major
> Fix For: 4.0.3, 4.2.0
>
>
> Given the following route:
> {code:java}
> public class Timer {
> ...
> static RouteBuilder timerRoute() {
> return new RouteBuilder() {
> private final AtomicInteger calls = new AtomicInteger();
> @Override
> public void configure() {
> // @formatter:off
> from(
> timer("timer")
> .period(Duration.ofMillis(100).toMillis())
> .fixedRate(true))
> .process(exchange -> {
> log.info("calls: {}", calls.incrementAndGet());
> exchange.getIn().setBody(new LargeObject());
> })
> .log("${body.fieldTwo}");
> // @formatter:on
> }
> };
> }
> }
> {code}
> and the following implementation of {{LargeObject}}
> {code:java}
> public class LargeObject {
> private static final Random RANDOM = new Random();
> byte[] data;
> String fieldOne;
> String fieldTwo;
> public LargeObject() {
> this.data = new byte[100 * 1024 * 1024]; // 100 MB
> RANDOM.nextBytes(data);
> fieldOne = UUID.randomUUID().toString();
> fieldTwo = UUID.randomUUID().toString();
> }
> }
> {code}
> We would expect that the program runs indefinitely. But if we limit the memory to e.g. ~3.2 GB (which is 10% of the whole system memory in my case) by running:
> {code:bash}
> java \
> -XX:MinRAMPercentage=10 \
> -XX:MaxRAMPercentage=10 \
> -XX:+ExitOnOutOfMemoryError \
> -jar ...
> {code}
> The program terminates with an {{OutOfMemoryError}} in the 32nd execution of the route.
> —
> [Reproducer 1 (pure camel, {{github.com}})|https://github.com/turing85/camel-lru-cache]
> [Reproducer 2 (quarkus camel, allow to define the size of the {{LargeObject}}, {{github.com}})|https://github.com/turing85/quarkus-camel-lru-cache]
> For both repositories, please read the {{README.adoc}} for instructions.
> —
> Observations:
> - For the quarkus-sample and a heap-limitation of ~3.2 GB, the breaking point is an {{object.size}} of {{2047K}}/{{2048K}}. With {{2047K}}, the program runs indefinitely, with {{2048K}}, the program crashes.
> - The problem also exist in native mode, but the breaking point is different
> - Looking at the implementation of the [{{SimpleLRUCache}} ({{github.com}})|https://github.com/apache/camel/blob/HEAD/core/camel-support/src/main/java/org/apache/camel/support/DefaultLRUCacheFactory.java#L150], it seems that this class is not using {{SoftReference}} s or {{WeakReference}} s. As far as I understand it, this means that if 1000 elements of whatever is stored in this cache exceed the heap limit of the JVM, the program will throw an {{OutOfMemoryError}} .
> - Conversely, this means that if a program "survives" the first 1000 calls, it will (most likely) run indefinitely.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)