Skip to content

Reduce memory consumption when repeatedly calling WritableJson.toByteArrayΒ #49428

Closed

Description

@System25

Enhancement request
Hi, we are using LogstashStructuredLogFormatter in our projects and it has affected the performance because the garbage collector is running a lot. After analyzing the allocated memory we have detected that the WritableJson.toByteArray method is the one to blame.

As far as I can see, you are using 2 buffers in memory for the same thing:

default byte[] toByteArray(Charset charset) {
	Assert.notNull(charset, "'charset' must not be null");
	try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
		toWriter(new OutputStreamWriter(out, charset));
		return out.toByteArray();
	}
	catch (IOException ex) {
		throw new UncheckedIOException(ex);
	}
}

The 2 buffers are:

  1. ByteArrayOutputStream buffer.
  2. OutputStreamWriter.se.bb (a ByteBuffer inside the StreamEncoder inside the OutputStreamWriter)

Do you think that you could use "toJsonString().getBytes()"? Or maybe use some kind of org.springframework.core.io.buffer.DataBuffer implementation?

Also, when you compare WritableJson with Jackson ObjectMapper, you see that the ObjectMapper includes a "BufferRecycler" to reduce the number of times that the garbage collection has to run.

Do you think that you could use something similar?

Thanks!

Activity

  1. philwebb commented on Mar 6, 2026

    @philwebb
    Member

    Thanks for the report @System25. I'm not sure that we can merge the ByteArrayOutputStream and the ByteBuffer inside the StreamEncoder since as far as I can tell the buffer in the StreamEncoder doesn't grow, where as the ByteArrayOutputStream does. We could possibly recycle the ByteArrayOutputStream buffers, but I think we still need to return a new byte[] so we're always going to have some garbage.

    Is there anything unusual about your setup? Are you logging a large amount of data? Can you also provide some background about how you found this issue? Are you using a specific tool to profile your application?

  2. System25 commented on Mar 6, 2026

    @System25
    Author

    Hi, there is nothing unusual about my setup. There is only a few log lines.
    I found the issue running a performance test and checking at the memory survivors report in Dynatrace.
    Dynatrace records the memory allocations and gives you a flame graph and the most memory allocations where there.
    Thanks!

  3. self-assigned this
    on Apr 29, 2026
  4. changed the title [-]WritableJson allocates too much memory[/-] [+]Reduce memory consumption when repeatedly calling WritableJson.toByteArray[/+] on Apr 30, 2026
  5. added and removed
    status: waiting-for-triageAn issue that has not yet been triaged. Contributions will not be accepted.
    on Apr 30, 2026
  6. added this to the 4.1.0 milestone on Apr 30, 2026
  7. philwebb commented on Apr 30, 2026

    @philwebb
    Member

    @System25 I've pushed something to main which should land in 4.1.0. Please give the SNAPSHOT a try to see if it improves things for you. I'm reluctant to call this a bug and backport it to earlier branches because the old code does work and an update like this is a little risky.

  8. added a commit that references this issue on Apr 30, 2026
    2fffebe
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions