Memory Leak in Jackson ObjectMapper's SerializerCache

3.7k Views Asked by At

Not quite sure if this is a Jackson question or a Springboot question, or Jetty:

My microservice became unresponsive in production apparently due to excessive memory usage (telling from OS RSS stat) but no OOM.

I obtained a heap dump via jcmd [pid] GC.heap_dump and later opened it in Eclipse Memory Analyzer Tool (MAT) installed via Eclipse Marketplace.

I'm greeted by this finding:

enter image description here

I think this says Jackson ObjectMapper ate 80% of my heap (395M out of the default 512M size).

What would cause this and how can I prevent it?

UPDATES

I started digging into Jackson's SeralizerCache.

There was indeed a reproducible memory leak but it was fixed in 2.7.x: https://github.com/FasterXML/jackson-databind/issues/1049

This SO question also applied to pre-2.7 versions: Too Many objects in single instance of ObjectMapper SerializerCache causing memory leak

My version is 2.13.1, so the above shouldn't matter.

1

There are 1 best solutions below

0
Alex R On BEST ANSWER

Found the culprit:

@PostMapping(value = "/headers", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@ResponseBody
public ListingHeader[] head(@RequestBody ListingDetailPK[] parms) {
    final ListingInfo[] all = readerDao.getAll(Arrays.asList(parms));
    ObjectMapper mapper = JSON.mapper().copy();
    mapper.registerModule(new MrBeanModule());
    try {
        return mapper.readValue(mapper.writerFor(ListingHeader[].class)
                .writeValueAsString(all), ListingHeader[].class);
    } catch (JsonProcessingException e) {
        throw new RuntimeException(e);
    }
}

A clue was provided in a comment by @Pawel Zieminski:

Is there a large number of (possibly generated) classes in your system? Some proxy classes maybe?

I suspect that the dynamic proxies generated by MrBeanModule are causing the problem.