【问题标题】:Spring Integration aggregator memory leakSpring Integration 聚合器内存泄漏
【发布时间】:2016-01-28 15:20:21
【问题描述】:

我们有一个小型弹簧集成通道系统,它会在应用程序的高负载时引入内存泄漏。我们创建这个示例应用程序只是为了测试 spring 聚合器。

SI Applicatiton Sample Git Project

Heap Dumps on both scenarios

Messenger 类中,我们控制提交线程在 1000 条消息传递到通道后休眠的时间量,然后再开始提交下 1000 条消息。

    public void run() {
    int correlationId = 0;
    while (true) {

        for (int sequenceNumber = 0; sequenceNumber < sequenceSize; sequenceNumber++) {
            Job jp = new Job(name);
            Message<Job> message2 = MessageBuilder.withPayload(jp)
           .setSequenceNumber(sequenceNumber)
           .setSequenceSize(sequenceSize)
           .setCorrelationId(correlationId).build();

           channel.send(message2);
        }

        try {
            Thread.sleep(100, 0);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        correlationId++;
        if (correlationId >= CORRELATION_ID_MAX) {
            correlationId = 0;
        }
    }

我们相信,在正常操作中,当它不占用内存时 TreeMap$Entry 会占用大量堆内存并具有很多实例,但是当将睡眠时间减少到非常低的量时 HashMap $Node开始成为问题

低负载时无内存泄漏

高负载内存泄漏时

HashMap$Node 将永远增加其内存利用率。

在接收到来自聚合器的聚合消息列表后,我们正在终端从通道 messageOutChannel 打印列表项延迟。

Time :   647 ms  List size : 1000   Hash : 875023460    By thread : th0  -FP

在内存泄漏情况下时间会不断增加,当没有发生内存泄漏情况时,它会稳定在一个数字附近。

希望有人能对此有所了解并说明我们在这里做错了什么? 谢谢

【问题讨论】:

  • 使用不同的MessageStore 默认情况下,所有消息都保存在内存中,直到聚合完成。有很多消息你可能不想要这个。默认情况下使用SimpleMessageStore,它使用Map 来存储消息。

标签: spring memory-leaks spring-integration


【解决方案1】:

这与聚合器无关;内存“泄漏”仅仅是因为您在任务执行器中排队了数以百万计的任务,并且您对其队列大小没有限制。

【讨论】: