Skip to content

ApplicationContext caches are not cleared as expected in integration tests if beans are lazy initialized #30954

Closed
@bgK

Description

@bgK

The test suite for our application using Spring Boot 3.1.1 recently started failing with OutOfMemoryError.

Analyzing the contents of the heap shows the following:
image
As expected, Spring keeps the last 32 contexts in memory for potential re-use. However the individual contexts seem quite large:
image
The resource cache for DefaultResourceLoader is responsible for much of the memory usage. It seems like this cache is intended to be cleared when the context initialization completes. When using lazy initialization, the initialization of the test class can cause the classpath to be scanned afterwards, filling the cache once again.

This is a minimal reproducer for such a case:

package org.example;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.web.servlet.MockMvc;

import static org.junit.jupiter.api.Assertions.assertTrue;

@SpringBootTest
@AutoConfigureMockMvc
@EnableAutoConfiguration
@TestPropertySource(properties = {
        "spring.main.lazy-initialization=true"
})
public class ReproTest {

    @Autowired
    private MockMvc mockMvc;

    @Autowired
    private DefaultResourceLoader defaultResourceLoader;

    @Test
    public void applicationContextResourceCacheShouldBeEmpty() {
        assertTrue(defaultResourceLoader.getResourceCache(MetadataReader.class).isEmpty());
    }

    @SpringBootConfiguration
    public static class ReproConfiguration {
    }
}

Should Spring ensure the resource cache is emptied when running tests to reduce memory usage?

Metadata

Metadata

Assignees

Labels

in: testIssues in the test moduletype: bugA general bug

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions